Ch. 17 · ServiceNow

ServiceNow Update Sets and Conflicts

How preview detects update set collisions, why a hotfix made directly in production causes most of them, and how to resolve each deliberately.

~6 min readadvancedupdated Oct 19, 2026

An update set is a container of customer updates. Each time you change a tracked configuration record (a business rule, a form layout, a dictionary entry) the instance writes an XML snapshot of that record into sys_update_xml and attaches it to your current update set. Promoting the set to another instance means retrieving it, previewing it, and committing it, which replays those snapshots on the target.

Preview is where things go wrong, and that’s where interview questions focus. “Preview shows 14 problems, what do you do?” is a better test of real experience than “what is an update set?”, because the right answer depends on why each problem exists.

How preview decides there’s a collision

ServiceNow’s documentation defines a collision as an update that has a newer local update. Preview compares each incoming customer update with what the target has recorded for the same update name, and if the target’s version was updated more recently, it flags the record. In the preview problems list this shows up as “Found a local update that is newer than this one”.

The update name is the key detail. For most record types it’s the table name plus the record’s sys_id, for example sys_script_include_4f2a19c0db10.... A small set of tables coalesce on meaningful columns instead. The documentation lists them: dictionary entries use table and element, sys_properties uses the name, roles and groups use the name, form sections and list layouts use name and view, and so on. For those, the same field created on two instances gets the same update name, and preview can tell they’re the same thing.

I modelled that rule in Node with three incoming updates from a release called R13, against a production instance with some history of its own:

const verdict = !local ? 'no local version: applies cleanly'
  : local.updated > u.updated ? `COLLISION: local update is newer (${local.updated} by ${local.by})`
  : 'older local version: incoming update replaces it';
JavaScript
VendorUtils script include         COLLISION: local update is newer (2026-10-14 09:12 by prod.admin (hotfix))
incident.u_vendor_ref max length   older local version: incoming update replaces it
Vendor escalation notification     no local version: applies cleanly
Text

The script include collides because someone edited it directly in production on 14 October, four days after the developer’s version in test. The dictionary change replaces an older release’s version, which is the normal case. The notification is the sneaky one: the model’s production instance already has a hand-built copy of the same notification with a different sys_id, so the names differ, preview sees nothing wrong, and after commit production has two escalation notifications. Every vendor escalation now sends two emails. Duplicates like that are worse than collisions, because nothing warns you.

Where collisions come from

Almost every collision has one of three causes.

Direct changes in a higher instance. An admin fixes a script in production during an incident. That fix is a customer update in production’s default update set, newer than anything in the pipeline. The next release carrying the same record collides with it, and if someone accepts the remote update, the fix disappears.

Two developers, one record. Two stories touched the same business rule in two update sets. Whichever set commits second meets the first set’s version. Preview catches this when the sets are committed into the same instance in the wrong order.

Out-of-order promotion. Update sets A and B both change a UI policy; B builds on A. If B is committed in production before A, then A arrives later with an older timestamp and preview flags it, or worse, A gets accepted and rolls the policy back.

Preview also reports problems that aren’t collisions, such as “Could not find a record in sys_ui_policy for column ui_policy referenced in this update”, which means the update depends on a record that hasn’t been promoted yet. That’s usually a missing update set, not something to skip.

Resolving each problem on purpose

For a collision, preview offers to accept the remote update (the incoming version wins) or skip it (the local version stays). Neither is safe by default. Open the comparison, look at the actual differences, and decide based on what each version contains.

For the VendorUtils example, the honest answer is often “neither”: the production hotfix and the developer’s change both matter. In that case, skip the remote update in production for now, take the production version back to development, merge the hotfix into the developer’s code there, test it, and send it up again in a new update set. The merged version then has a newer timestamp than production’s hotfix and commits cleanly. That takes longer than clicking “accept” but it’s the only path where neither change is lost.

For out-of-order problems, the fix is to commit the sets in the right order. Batched update sets (a parent with children) exist for this: preview and commit the batch together and the platform handles the sequence.

For missing references, find which update set contains the missing record and promote it first, or include it in the same batch. Skipping such an update usually leaves broken configuration on the target.

Gotcha

Never fix a collision by editing the record in production to match. That creates another newer local update and makes the next release collide again.

Habits that keep preview quiet

Most teams can get preview down to zero or one problem per release with a few rules:

  • No configuration changes in production outside the pipeline. If an emergency fix is unavoidable, make it in its own named update set in production, export it, and load it into development and test the same day, so the pipeline catches up.
  • One record, one owner per release. When two stories touch the same script, put them in the same update set or sequence them explicitly in a batch.
  • Promote, don’t rebuild. Create configuration once and move it with update sets or XML export, so sys_ids match everywhere. Rebuilding by hand on another instance is how the duplicate notification above happened.
  • Keep environment values out of update sets. Endpoint URLs, credentials and anything that differs per instance belong in properties marked private or in per-instance configuration, so promotions don’t overwrite them.
  • Preview in test first. If test is cloned regularly from production, a preview there shows you the production problems before the change window.

Clones help too. Cloning production down to test resets test to production’s state, including any hotfixes, so the next preview in test reflects reality. Just remember to back up in-progress update sets on the target before cloning over it.

Interview practice: fourteen problems in the change window

You’re committing a release update set to production at 9 p.m. Preview shows 14 problems: 11 “Found a local update that is newer than this one” on script includes and business rules, and 3 “Could not find a record” errors. The change manager asks whether you can just accept all and commit. What do you say, and what do you do?

Answer

I’d say no. Accepting every collision means replacing 11 newer production versions with older ones from the release, and if any of those production versions contain hotfixes, we’d be rolling back live fixes without knowing it. The three missing references mean the release depends on records that aren’t in production yet, so committing would leave broken configuration. I’d look at the 11 collisions first: compare each one and check who changed the production version and when. If they’re all from a single emergency fix, the right move is to postpone this release, merge those fixes into development, and retest. If a few are trivial (for example, a production edit that only changed a comment), I’d skip those individually and note them. For the missing references, I’d find the update set that contains them; usually it’s an earlier release that wasn’t promoted, which also suggests the batch was put together wrongly. Then I’d agree with the change manager on a new window, and afterwards raise a problem record about direct production changes so it doesn’t keep happening.

More in ServiceNow

read ✓ServiceNow · hard

ServiceNow Update Sets and Deployment Scope

Know what a ServiceNow update set carries and what it leaves behind: configuration versus data, preview problems and environment values.

~7 min readread →
read ✓ServiceNow · hard

ServiceNow ACL Scripting and Access

When an ACL really needs a script, how to write one that is cheap and null-safe on every row, and how to prove it works by testing as the user.

~7 min readread →
esc