We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

MohammedSAli
ServiceNow Employee

 

🔎 Troubleshooting & Preventing Duplicate Task Numbers in ServiceNow

A complete guide to understanding, detecting, and enforcing unique numbering on Task and Task child tables

Duplicate numbering on Task or its child tables (Incident, Problem, Change, etc.) is rare—but when it occurs, it can impact reporting, integrations, and user trust in the platform.

This article explains:

  • Why duplicates occur
  • How to detect duplicates (GlideRecord scripts included)
  • How to fix numbering issues
  • How to enforce unique numbering going forward

1. Why Duplicate Numbers Occur

Out of the box, ServiceNow does not enforce uniqueness on the task.number field. This means the database will allow two or more records with identical numbers unless you enforce constraints.

Common Causes

A) Double inserts caused by UI actions

  • Multiple rapid clicks on Submit or Save
  • Browser automation tools triggering actions twice
  • Latency causing resubmission when a user thinks submitting failed

B) Business Rule creating an unintended second insert

Example:

current.insert();  // inside a before/after insert BR → creates duplicates

C) Scripted inserts using workflows, script includes, or integrations

Any logic that inserts a Task record without proper guards can generate duplicates.

D) Clone or data import inconsistencies

If a cloned target already contains a number sequence ahead of the source, duplicates may arise after clone/import.

E) Autonumbering collisions under heavy load

The default sequential numbering is not atomic — two inserts occurring simultaneously may generate the same number before either commit completes.


2. How to Detect Duplicate Numbers

You can run the following scripts in Background Scripts to identify duplicate numbers on Task or any child table.

A) Find duplicate numbers on Task


var dup = new GlideAggregate('task');
dup.addAggregate('COUNT', 'number');
dup.groupBy('number');
dup.addHaving('COUNT', '>', 1);
dup.query();

while (dup.next()) {
  gs.print('Number: ' + dup.number + ' | Count: ' +
           dup.getAggregate('COUNT', 'number'));
}

B) Retrieve the actual duplicate records

Replace TASKNUMBER with the number you found above:


var gr = new GlideRecord('task');
gr.addQuery('number', 'TASKNUMBER');
gr.query();

while (gr.next()) {
  gs.print(gr.sys_id + ' | ' + gr.number + ' | ' +
           gr.sys_created_on);
}

C) Check child tables only (Example: Incident)


var dup = new GlideAggregate('incident');
dup.addAggregate('COUNT', 'number');
dup.groupBy('number');
dup.addHaving('COUNT', '>', 1);
dup.query();

while (dup.next()) {
  gs.print('Duplicate Incident: ' + dup.number);
}

3. Fixing Existing Duplicate Numbers

If duplicates already exist, you must either renumber or delete/archive invalid records before enforcing uniqueness.

Options

Option A: Reassign new numbers to duplicates

You can modify the number field using:

  • Fix scripts
  • A one‑time update script
  • A Business Rule that triggers only on existing duplicates

Option B: Delete invalid duplicates

Only if the instance owner agrees and the data is not required.


4. Preventing Future Duplicates (Enforcing Unique Numbering)

There are two fully supported approaches:

A) Preferred Method: Before Insert Business Rule

This is the method recommended in official documentation.

Create a Before Insert Business Rule on Task (set Apply to extended tables = true so child tables inherit it):


(function executeRule(current, previous /* null when async */) {

  var num = current.number + '';
  if (!num)
    return;

  var rec = new GlideRecord(current.getRecordClassName());
  rec.addQuery('number', num);
  rec.setLimit(1);
  rec.query();

  if (rec.next()) {
    // Number already exists – assign next available
    var newNum = getNextObjNumberPadded(); // system function
    gs.addInfoMessage(
      "Duplicate number detected. Changing '" + num +
      "' to '" + newNum + "'."
    );
    current.number = newNum;
  }

})(current, previous);

Why this helps

  • Prevents duplicates before the record is saved
  • Requires no database schema changes
  • Automatically applies to Task and all child tables

When to choose this

✔ Mixed workloads ✔ High insert volume ✔ When graceful recovery is preferred over hard errors

B) Alternative Method: Unique Index on task.number

You can enforce uniqueness at the database level:

  • System Definition → Tables → Task → Columns → number → Unique = true
  • Or create a custom index under Database Indexes

Pros

  • Hard guarantee of uniqueness
  • Enforced at database level

Cons

  • Insert attempts fail with an error
  • All existing duplicates must be resolved first
  • May break integrations or scripts with incorrect numbering logic

5. Additional Recommendations

 

A) Review all custom Business Rules and Flows

Search for:

  • current.insert()
  • current.update() inside insert Business Rules
  • Flows or ACLs referencing the number field

B) Check for automation tools causing double submits

Bots and browser automations often behave differently than humans.

C) Review logs

If the issue is intermittent:

  • syslog_transaction
  • Node logs for simultaneous inserts
  • Slow Business Rules preceding failures

6. Summary

  • Duplicate numbers occur because OOTB numbering does not enforce uniqueness
  • Duplicates can be detected using GlideRecord / GlideAggregate scripts
  • Fix existing duplicates before enforcing constraints
  • Use a Before Insert Business Rule or a Unique Index to prevent recurrence
  • Audit automations, scripts, and integrations for double inserts
1 Comment
Antony_Alldis
ServiceNow Employee

Thank you Mohammed.

 

This is a really great article, explaining how (and why) this occurs OOB, and how to prevent it from happening!