Marking a Customer Update "replace on upgrade" is how an admin tags an record for replacement in the next upgrade. However, when marking a Customer Update "replace on upgrade" and then making further customizations for the same record, the system remembers your decision to replace on upgrade independent of your other updates for as long as you continue working in the same update set.
The Default update set is the most extreme example of this. If working with the default update set, it's unlikely you'll remember marking something replace on upgrade, possibly months or years ago, and of course someone else might have done the marking.
The preservation of the "replace on upgrade" flag leads to the system overwriting your customization, despite no longer desiring that outcome.

Steps to Reproduce

  1. Update a record in the Default Update Set
  2. Revert that record to Base System (or find the sys_update_xml record for that update and set replace_on_upgrade = true)
  3. Modify the record again in the Default update set
The record is still replace on upgrade


Procedural Workaround

A typical work pattern with Revert to Base Version automatically clears the flag on your next change to the record, because the revert is in a separate update set. The work pattern is like this:

  1. On dev, create an update set to track items reverted to base version
  2. Review your customizations after upgrading dev, including reverting to base version and merging as appropriate
  3. When you're done reviewing, complete that update set
  4. After upgrading test, apply that update set
  5. After upgrading prod, apply that update set

At the end of this process, all the instances have a customer update with replace_on_upgrade=true, but it's in a completed update set. If a developer edits the record, their current update set will be a different update set, and the flag will be false on the new Customer Update. It is not possible, when following this methodology, to encounter the PRB.

Case-by-Case Workaround

It's worth noting that this workaround is not necessary if adopting the Procedural Workaround methodology above.

The core problem here is the use of an update set that is long-lived. There are two ways to work around the problem on a case-by-case basis. Both involve setting up a "Revert to Base Version" update set for each scope in which you revert (for most customers, this will just be one update set in the Global scope).

Once the set is configured, simply switch to it whenever reverting, and only when reverting. Switch back to the usual update set(s) after reverting.

If you forget to switch before reverting, simply edit the Customer Update record with replace_on_upgrade=true to set its Update Set to be the "Revert to Base Version" set.

By separating your "real work" in one set -- where replace_on_upgrade is always false -- and your "Revert to Base Version" work in another set -- where replace_on_upgrade is always true -- the appropriate replace_on_upgrade flag will be considered by each subsequent upgrade. Because the upgrade engine considers the sys_update_xml with the most recent sys_recorded_at, and no developer ever updates a sys_update_xml record that already has replace_on_upgrade set to an undesired value, you will not experience unexpected customization overwrites on upgrade.

Related Problem: PRB1239377

Seen In

There is no data to report.

Intended Fix Version

Jakarta Patch 9
Kingston Patch 4

Safe Harbor Statement

This "Intended Fix Version" information is meant to outline ServiceNow's general product direction and should not be relied upon in making a purchasing decision. The information provided here is for information purposes only and may not be incorporated into any contract. It is not a commitment, promise, or legal obligation to deliver any material, code, or functionality. The development, release, and timing of any features or functionality described for our products remains at ServiceNow's sole discretion.

Associated Community Threads

There is no data to report.

Article Information

Last Updated:2018-03-20 10:34:27