PlanRecursionException in Bidirectional Stage-Based Flows: Least Invasive Solution?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
17 hours ago
Hi ServiceNow Community,
I am looking for advice on the least invasive and most upgrade-safe solution to address a PlanRecursionException, without increasing the platform recursion limit.
We have implemented a stage-based process on a custom Case table.
When a Case is created, the process is managed through multiple record-triggered flows operating on the same Case record.
The design works as follows:
- Each flow is associated with a specific stage.
- A flow is triggered when the stage field changes to the corresponding value.
- The flow performs the activities required for that stage.
- At the end, the flow updates the same Case record by setting the stage field to the value expected by the trigger of the next flow.
In a simplified forward path:
However, the process is bidirectional. A Case can both advance and move back to a previous stage.
For example, when an approval is rejected or not granted, the current flow may set the stage field back to a previous value:
Therefore, returning to an earlier stage is an expected business scenario, not necessarily an unintended technical infinite loop. Nevertheless, this backward transition re-enters a flow that has already been part of the current execution chain, which appears to be the reason why ServiceNow detects plan recursion.
The preceding flow is shown as Completed, and the Case record is updated correctly. However, the flow associated with the new stage is not created in the Flow Executions list.
The system log contains the following error:
The stack trace shows that the error occurs after a RecordUpdateOperation.
The apparent sequence is:
This is particularly relevant in the rejection path:
From a business perspective, the Case must legitimately return to Stage A and repeat some or all of the processing associated with that stage. From the Flow Designer engine perspective, however, this seems to be considered recursion because the same flow plan is started again within the existing execution chain.
We would prefer not to:
- increase the recursion limit;
- redesign the entire process;
- remove the ability to return to a previous stage;
- lose the modularity provided by having one flow for each stage.
What would be the recommended and least invasive approach for this scenario?
Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10 hours ago
Hey @ClaudioG4376288,
// End of Flow A / Flow B, replace the direct
// "Update Record" step on Case with:
gs.eventQueueScheduled('case.stage.transition', current, current.stage.toString(), '', gs.now());Point the downstream flow's trigger at the sysevent table instead of Case (add sysevent to sn_flow_designer.allowed_system_tables if it isn't selectable yet), filtered on that event name. The stack trace names com.glide.flow_trigger.engine.RecordTriggerRunner specifically, that's the piece walking the current plan's execution chain and blocking re-entry into a flow already in it. An event fired this way runs on its own transaction, so the next stage's flow starts a fresh execution chain instead of nesting inside the one Flow A is still part of. No recursion limit change, no redesign, each stage keeps its own flow.
Thank you,
Vikram Karety
Octigo Solutions INC