logo

NJP

ServiceNow Error when copying flow: "Label cache error: Table not found"

ServiceNow Blog · Dec 10, 2025 · article

ServiceNow Error when copying flow

Label cache error: Table not found: x_cls_clear_skye_i_identity_settings: Label cache error: Table not found: x_cls_clear_skye_i_identity_settingswhen copying the promote profile subflowreproduceable on 5.2 and 3

KB1575415 - How To Remove Unnecessary Label Cache Entries of a Flow/Subflow/Action

11:43

Apparently, running the background script detailed in the SN KB should resolve the issue

once happy, modify the fix script below to set debugmode to false

---

Fix script:

// README

// This script updates and removes unnecessary label cache entries of a flow/subflow (defintion and master snapshot).

//

// IMPORTANT NOTES:

// This script only deletes the unnecessary label cache in the server. UI can hold a copy of a label cache.

// Therefore refresh the browser that has the action opened once this script is executed for the action.

// If this script is executed and the action is saved using UI, the previous label cache (before the delete)

// will be saved since the label cache from the UI will be sent to the server and saved.

// Script Parameters

// If true then do not actually modify the flow/subflow's label cache (debug mode). If false then update the flow/subflow's label cache (real mode).

var debugMode = true;

// If empty, then execute for all flow/subflow definition and master snapshot files. Otherwise, only run for the flow/subflow/action with name = targetName.

var targetName = "";

// If true then it logs more debug messages.

var skipDetails = false;

// Code

var missCount = 0;

var hitCount = 0;

var numberOfRecordsModified = 0;

var numberOfFlowsModified = 0;

var flowsModified = {};

function cleanFlowLabelCache(flow, debug, flowVersion) {

var flowModified = false;

printWithName(flow.name, "Attempting to clean the label cache for flow/subflow \'" + flow.name + "\' with sys id \'" + flow.sys_id + "\' which is on the table " + flow.sys_class_name);

if (isEmpty(flow.label_cache) || flow.label_cache == "[]") {

printWithName(flow.name, "Has an empty label cache");

} else {

var pills = getPills(flow.sys_id, flowVersion);

// removes control characters in unicode (ex: \n), which the inclusion will cause a thrown exception in JSON.parse()

flow.label_cache = flow.label_cache.toString().replace(/[\u0000-\u001F\u007F-\u009F]/g, "");

var label_cache = {};

try {

label_cache = JSON.parse(flow.label_cache);

} catch(e) {

gs.print("Exception thrown. Message: " + e.message + " Stack trace: " + e.stack);

}

printWithName(flow.name, "Original label cache before the removal:\n" + flow.name + ": " + flow.label_cache);

var newLabelCache = [];

for (var labelKey in label_cache) {

if (pills[label_cache[labelKey].name] || pills['{{' + label_cache[labelKey].name + '}}'] ) {

if (skipDetails == false)

printWithName(flow.name, "We have a match " + label_cache[labelKey].name);

newLabelCache.push(label_cache[labelKey]);

hitCount++;

} else {

if (skipDetails == false)

printWithName(flow.name, "We have a miss " + label_cache[labelKey].name);

missCount++;

flowModified = true;

}

}

flow.label_cache = JSON.stringify(newLabelCache);

printWithName(flow.name, "New label cache after the removal:\n" + flow.name + ": " + flow.label_cache);

if (debug == false)

flow.update();

}

return flowModified;

}

function isEmpty(obj) {

return !obj || (Object.keys(obj).length === 0 && obj.constructor === Object)

}

function getPills(flowId, flowVersion) {

var pills = {};

var instances = new GlideRecord("sys_hub_flow_component");

instances.addQuery("flow", flowId);

instances.query();

while(instances.next()) {

if (flowVersion == "2") {

findPillsInInstanceCompressedString(instances, pills);

} else {

findPillsInMapping(instances.sys_id, pills);

findPillsInVariableValue(instances.sys_id, pills);

}

}

findPillsInMapping(flowId, pills);

findPillsInVariableValue(flowId, pills);

if (flowVersion == "2") {

findPillsInTriggerInstanceV2(flowId, pills);

} else {

findPillsInTriggerInstance(flowId, pills);

}

return pills;

}

function getUncompressedValue(compressedValues) {

if (skipDetails == false)

gs.print("compressedValues: " + compressedValues);

var values = "";

if (compressedValues)

values = new GlideCompressionUtil().expandToString(new GlideStringUtil().base64DecodeAsBytes(compressedValues));

if (skipDetails == false)

gs.print(values);

return values;

}

function findPillsInInstanceCompressedString(instances, pills) {

var tableName = null;

if (instances.sys_class_name == "sys_hub_action_instance_v2") {

tableName = "sys_hub_action_instance_v2";

} else if (instances.sys_class_name == "sys_hub_sub_flow_instance_v2") {

tableName = "sys_hub_sub_flow_instance_v2";

} else if (instances.sys_class_name == "sys_hub_flow_logic_instance_v2") {

tableName = "sys_hub_flow_logic_instance_v2";

}

if (tableName) {

var instanceGr = new GlideRecord(tableName);

if (instanceGr.get(instances.sys_id)) {

var compressedValues = null;

if (tableName == "sys_hub_sub_flow_instance_v2")

compressedValues = instanceGr.subflow_inputs + '';

else if (tableName == "sys_hub_action_instance_v2" || tableName == "sys_hub_flow_logic_instance_v2") {

compressedValues = instanceGr.values + '';

}

if (compressedValues) {

var values = getUncompressedValue(compressedValues);

findPillsInValue(values, pills);

}

}

}

}

function findPillsInTriggerInstanceV2(flowId, pills) {

var triggerInstance = new GlideRecord("sys_hub_trigger_instance_v2");

triggerInstance.addQuery("flow", flowId);

triggerInstance.query();

// should be at max one result in triggerInstance

while(triggerInstance.next()) {

var compressedValues = triggerInstance.trigger_inputs + '';

var values = getUncompressedValue(compressedValues);

findPillsInValue(values, pills);

}

}

function findPillsInTriggerInstance(flowId, pills) {

var triggerInstance = new GlideRecord("sys_hub_trigger_instance");

triggerInstance.addQuery("flow", flowId);

triggerInstance.query();

// should be at max one result in triggerInstance

while(triggerInstance.next()) {

var triggerInstanceId = triggerInstance.sys_id;

var sysVariableValue = new GlideRecord("sys_variable_value");

sysVariableValue.addQuery("document_key", triggerInstanceId);

sysVariableValue.query();

while(sysVariableValue.next()) {

var value = sysVariableValue.value;

findPillsInValue(value, pills);

}

}

}

function findPillsInMapping(id, pills) {

var elementMapping = new GlideRecord("sys_element_mapping");

elementMapping.addQuery("id", id);

elementMapping.query();

while(elementMapping.next()) {

var value = elementMapping.value;

findPillsInValue(value, pills);

}

}

function findPillsInVariableValue(id, pills) {

var variableValue = new GlideRecord("sys_variable_value");

variableValue.addQuery("document_key", id);

variableValue.query();

while(variableValue.next()) {

var value = variableValue.value;

findPillsInValue(value, pills);

}

};

function findPillsInTransform (value, pills) {

// removes "{{fd_transform:" prefix and "}}" postfix

if (value && value.length > 16) {

var uuid = value.substring(15, value.length - 2);

var pillCompound = new GlideRecord("sys_hub_pill_compound");

pillCompound.addQuery("ui_id", uuid);

pillCompound.query();

while (pillCompound.next()) {

var prescription = pillCompound.prescription;

if (skipDetails == false)

gs.print("Prescription value: " + prescription);

findPillsInValue(prescription, pills);

}

}

};

function findPillsInValue (value, pills) {

var result;

var PILL_REGEX = /{{(?!{)([}]*)}}/g;

while(result = PILL_REGEX.exec(value)) {

if (result[0] && result[0].startsWith("{{fd_transform:") && result[0].length > 16) {

findPillsInTransform(result[0], pills);

} else {

pills[result[0]] = true;

}

if (skipDetails == false)

gs.print("Pill value: " + result[0]);

}

};

function findPillsInErrorHandling(id, pills) {

var errorHandlingMetadata = new GlideRecord("sys_hub_action_status_metadata");

if (!errorHandlingMetadata.get("action_type_id", id))

return;

var statusCondition = new GlideRecord("sys_hub_status_condition");

statusCondition.addQuery("action_status_metadata_id", errorHandlingMetadata.sys_id);

statusCondition.query();

while (statusCondition.next()) {

findPillsInValue(statusCondition.status, pills);

findPillsInValue(statusCondition.condition, pills);

}

}

function printWithName(name, text) {

gs.print(name + ": " + text);

}

var modified;

gs.print("Debug mode: " + debugMode);

if (debugMode == false)

gs.print("This is an actual execution that updates the label cache");

else

gs.print("This is a test run that does not actually update the label cache");

var flows = new GlideRecord("sys_hub_flow_snapshot");

flows.addQuery("master", true);

if (targetName)

flows.addQuery("name", targetName);

flows.query();

while (flows.next()) {

var version = flows.getValue("version");

var flowVersion = "1";

if (version == "2") {

flowVersion = "2";

}

modified = cleanFlowLabelCache(flows, debugMode, flowVersion);

if (modified) {

numberOfRecordsModified++;

if (!flowsModified[flows.name]) {

flowsModified[flows.name] = true;

numberOfFlowsModified++;

}

}

}

flows = new GlideRecord("sys_hub_flow");

if (targetName)

flows.addQuery("name", targetName);

flows.query();

while (flows.next()) {

var version = flows.getValue("version");

var flowVersion = "1";

if (version == "2") {

flowVersion = "2";

}

modified = cleanFlowLabelCache(flows, debugMode, flowVersion);

if (modified) {

numberOfRecordsModified++;

if (!flowsModified[flows.name]) {

flowsModified[flows.name] = true;

numberOfFlowsModified++;

}

}

}

gs.print("Total number of label cache entries removed: " + missCount);

gs.print("Total number of label cache entries kept (not removed): " + hitCount);

gs.print("Total number of flow/subflow definition and master snapshot records modified: " + numberOfRecordsModified);

gs.print("Total number of unique flow flow/subflow modified: " + numberOfFlowsModified);

View original source

http://www.cloudminus89.com/2025/12/servicenow-error-when-copying-flow.html