[object Object]

The category dropdown on the incident form has 47 entries, including “Hardware,” “hardware,” “HW,” and “Hardware (legacy).” The reporting analyst spends every Monday morning normalizing the data because the dashboard breaks otherwise. Choice lists are easy to add to and almost impossible to remove from once data references them. The discipline starts on day one or it never starts.

Naming convention before population

Decide casing, abbreviation, and ordering before populating any choice list. “Title Case” or “Sentence case” — pick one and never mix. Spell out terms or abbreviate consistently — never “Database” in one row and “DB” in another. Order alphabetically or by frequency, but pick a rule. The first 10 values set the precedent everyone else copies.

Use sys_choice for global, not local

A choice value defined on the field has table-local scope; a choice value defined in sys_choice is reusable. For widely-shared values (severity, priority, region), use sys_choice with proper scoping. Local choices are fine for table-specific values; mixing them on the same field produces visible duplicates that look the same but behave differently.

Field: incident.category
Source: sys_choice (table=task, element=category)
NOT: locally defined values overriding sys_choice

Inactive, not deleted

Choice values referenced by historical records cannot be safely deleted — the references would render as raw labels or display blank. Mark them inactive instead. Inactive values do not appear in new dropdowns but render correctly on historical records. The “delete the value” button is the most dangerous control on the choice list editor.

Sequence numbers, not display order from creation

Choice lists default to creation-order display. Six months later, the order is meaningless. Set explicit sequence values in increments of 10 (10, 20, 30…) so insertions between values do not require renumbering everything. Sort alphabetically only when the choice values are consistently labeled and the user expects alphabetical (e.g., countries).

Translation tables for multi-language

In a localized instance, choice values need translations in sys_choice per language. Adding a value in English without adding translations leaves users in other locales seeing English labels (or worse, blank). The translation completion check belongs on the choice value lifecycle — a value is not “live” until all required-language translations are complete.

Programmatic adds need approval

A scripted bulk import that adds 50 new categories without review is the most common source of choice list bloat. Wrap programmatic adds in a Service Catalog request that captures the business justification, the proposed value, the duplicate-check evidence, and an owner. Auto-grant for clear cases; route ambiguous adds to a curator role.

// Helper to check before adding
function findChoiceDuplicates(table, element, label) {
  var gr = new GlideRecord('sys_choice');
  gr.addQuery('name', table);
  gr.addQuery('element', element);
  gr.addQuery('label', 'CONTAINS', label.toLowerCase());
  gr.query();
  var matches = [];
  while (gr.next()) matches.push({value: gr.value+'', label: gr.label+''});
  return matches;
}

Quarterly retirement review

Run a quarterly job: for each major choice list, count usage of each value over the trailing 12 months. Values with zero usage are retirement candidates; values with one-off usage are dedupe candidates. Surface the report to the data owner, mark approved retirements as inactive, and document the decision. Without this loop, dead values accumulate forever.

Common failure modes

Choice value used as a routing key in a script include — retiring the value silently breaks the routing. Maintain a cross-reference of script-referenced choice values and require code update before deactivation. Choice list edited directly in production without an update set — common because the editor is so easy; restrict edit permission to a maintainer role.

What changed in 2026

Workspace forms render choice lists with type-ahead by default, which mitigates the user pain of long lists. The data quality problem is unchanged; type-ahead just hides the bloat. The dashboard breakage is the same.

What to do this week: pick the choice list with the most values on your busiest table; sort by usage count; the bottom quartile is your retirement candidate list.

[object Object]
Share