A small label tweak to the “Delivery Address” Variable Set goes live and 30 catalog items render with mismatched form layouts the next morning. The intent of Variable Sets is exactly this leverage — but the leverage works in both directions. Variable Sets without governance turn a single edit into a cross-cutting incident.
Variable Sets are libraries, treat them like code
A Variable Set used by 30 items is a shared library. Edits should follow the same discipline as a code library change: review, test against consumers, version, communicate. The catalog UI lets anyone with catalog_admin edit a Variable Set in production with no consumer awareness. Lock that down to a maintainer role and route changes through Service Catalog for catalog changes.
Catalog-shared vs item-shared sets
Two distinct reuse patterns exist. A “Delivery Address” set is shared across many catalog items (catalog-shared) — change rarely, version carefully. A “Hardware Specifications” set used by three variants of the same item (item-shared) — change with the item, no separate versioning needed. Treat them differently; the governance overhead for catalog-shared sets is justified by the blast radius.
Naming convention with the consumer count
Name Variable Sets with their domain and consumer count visible in the description: “Delivery Address (used by 30 items)”. A scheduled job updates the count weekly. Maintainers know at a glance which sets are heavily shared and which are local — and which renames or restructures will hurt.
// Update consumer count
function updateVariableSetConsumerCount(setSysId) {
var rel = new GlideAggregate('io_set_item');
rel.addQuery('variable_set', setSysId);
rel.addAggregate('COUNT');
rel.query();
rel.next();
var count = rel.getAggregate('COUNT');
var set = new GlideRecord('item_option_new_set');
set.get(setSysId);
set.short_description = set.short_description.split(' (')[0] + ' (used by ' + count + ' items)';
set.update();
}
Variable order is per-item, not per-set
A surprise: variable display order on the catalog form is configured per item, not per Variable Set. Adding a new variable to a shared set inserts it at the bottom of the set; on each consuming item, the integration with surrounding variables may render awkwardly. Plan layout review per consumer when sets gain variables, not just when items gain variables.
UI Policies on Variable Sets
UI Policies defined at the Variable Set level apply to every consumer. Useful for set-internal logic (“hide City when Country is empty”). Dangerous for cross-variable logic that assumes context outside the set. Keep set-level UI Policies strictly to the set’s own variables; never reference variables from the parent catalog item.
Conditional set inclusion
A Variable Set can be conditionally included on an item via a Catalog UI Policy (“show this set when delivery method is ‘shipping’”). Use this for genuinely conditional groups. Do not use it as a workaround for not wanting to think about whether the set belongs on the item — every conditional set adds form rendering overhead and audit complexity.
Common failure modes
Two Variable Sets with overlapping variables (both have a “city” variable) on the same item — last-rendered wins, validation gets confusing. Use unique variable names across all sets used on a given item. Variable Set referenced by an item but the set itself is inactive — variables disappear silently from the form. Add a validation rule: an active item cannot reference an inactive set.
Implementation sequence
Inventory existing Variable Sets, count consumers, identify the top 10 by consumer count. Establish governance for those (maintainer role, change process, notification list). Lower-volume sets follow the same governance lazily — when they next change. Trying to migrate every Variable Set to formal governance on day one is a project for a quarter.
What to do this week: count items per Variable Set in io_set_item; the top five by count are your governance priority; the bottom decile is your retirement candidate list.