Built something you're proud of? Tell the story. A quick G2 review of App Engine or Build Agent helps other developers see what's possible on ServiceNow. Share your experience.

Demand creating EAP Epic twice

Jo_o Pedro
Tera Guru

Basically when I click on the "Create EAP Epic" (first image) UI Action link, sometimes it duplicates the Epic generated. It occurs in both Next Experience and Strategic Planning Workspace.

 

When I create the epic, it closes the demand but it's creating an epic with the "converted_from" field populated with the demand name, and another epic exactly the same as the first but with the "converted_from" empty. Both are always created seconds apart.

 

Has anyone seen this behavior before? Any idea what could be causing the duplicate execution?
The Ui Action is OOTB

1 ACCEPTED SOLUTION

Hi, Naveen

 

I discovered what was happening. It was a Business Rule calling a Script Include, which eventually called a subflow.

The BR "Sync Data from Alignment to Execution" (OOTB) calls the include "APWCommonIntegrationUtils" (OOTB) and this include eventually calls the subflow "syncDataFromAlignmentToExecution" (OOTB).

 

The problem was that sometimes the integration was delayed and because of this the epic was sometimes duplicated.

 

I added the following check in the beginning of the BR and it solved the problem

 if (current.sys_class_name == 'sn_align_core_scrum_epic' && !gs.nil(current.execution_entity_item)) {
        return;
    }




View solution in original post

2 REPLIES 2

Naveen20
ServiceNow Employee

Fact that one Epic has converted_from populated and the other doesn't is the key clue — it strongly suggests two different code paths are both creating an Epic, not a single action firing twice.

Here's what's most likely happening:

The UI Action "Create EAP Epic" creates the first Epic (with converted_from populated) and then sets the Demand state to Completed. A separate Business Rule or Flow on the Demand table is listening for that state change to "Completed" and creates a second Epic (without converted_from, since that flow doesn't know about the conversion context).

How to confirm and fix:

  1. Check for Business Rules on dmn_demand that trigger on state change to Completed — look for any that insert into the Epic table (pm_project or whichever table your Epics live on). Also check Flow Designer for flows triggered by Demand state changes.

  2. Enable the SQL Debug session (glide.security.debug.sql or just session debug on transactions) right before clicking "Create EAP Epic." The system log will show you exactly which script/BR/flow is doing each insert, with stack traces. Look for two separate INSERT statements on the Epic table.

  3. As a quick validation, open the two duplicate Epics and check sys_created_by — if they differ (e.g., one is the current user, the other is system or a flow context user), that confirms two separate execution contexts.

If it turns out to be a single path firing twice (same sys_created_by, same converted_from value on both), then it's likely a double-click or Next Experience re-rendering issue. In that case, add a mutual exclusion check at the top of the UI Action server script — something like a GlideRecord query to see if an Epic with that converted_from already exists before creating another one.

Since the UI Action is OOTB, I'd recommend checking the ServiceNow Known Error (KE) database or filing an HI case if you confirm it's a platform-level race condition. The SPM/ITBM module has had duplicate creation bugs in past releases, especially around the Demand-to-Epic conversion flow.

Hi, Naveen

 

I discovered what was happening. It was a Business Rule calling a Script Include, which eventually called a subflow.

The BR "Sync Data from Alignment to Execution" (OOTB) calls the include "APWCommonIntegrationUtils" (OOTB) and this include eventually calls the subflow "syncDataFromAlignmentToExecution" (OOTB).

 

The problem was that sometimes the integration was delayed and because of this the epic was sometimes duplicated.

 

I added the following check in the beginning of the BR and it solved the problem

 if (current.sys_class_name == 'sn_align_core_scrum_epic' && !gs.nil(current.execution_entity_item)) {
        return;
    }