Flow Designer Ask For Approval Recursion

Amane1
Giga Guru

Hello Community.

 

Version: 
Vancouver

 

Symptom: 

Ask for approval within flow designer is not working properly. Ask for approval step will be cancelled and the approval state is [No longer required] every time it runs. I have checked the flow log and it says: 

Failed to run flow trigger for trigger runner: b54b5f30c30052103d7333e015013139 of class: class com.glide.flow_trigger.engine.RecordTriggerRunner on record: <<table_name>> (7f5fc3b0c3cc12103d7333e015013135): com.snc.process_flow.exception.PlanRecursionException: Plan recursion has been encountered
at com.snc.process_flow.engine.GlideProcessAutomation.checkRecursion(GlideProcessAutomation.java:1136)
at com.snc.process_flow.engine.GlideProcessAutomation._start(GlideProcessAutomation.java:580)
at com.snc.process_flow.engine.GlideProcessAutomation$StartBuilder.start(GlideProcessAutomation.java:1532)
at com.glide.flow_trigger.engine.TriggerRunner.startFlow(TriggerRunner.java:119)
at com.glide.flow_trigger.engine.RecordTriggerRunner.run(RecordTriggerRunner.java:95)
at com.glide.flow_trigger.engine.TriggerEngine.runEngine(TriggerEngine.java:97)
at com.glide.policy.AScriptEngine.process(AScriptEngine.java:34)
at com.glide.script.ScriptEngines.lambda$run$0(ScriptEngines.java:106)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at com.glide.script.ScriptEngines.lambda$run$1(ScriptEngines.java:104)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at com.glide.script.ScriptEngines.run(ScriptEngines.java:103)
at com.glide.script.GlideRecord.runEngines(GlideRecord.java:1409)
at com.glide.script.GlideRecord.runScriptsAndEngines(GlideRecord.java:1390)
at com.glide.script.GlideRecord.postChange(GlideRecord.java:5373)
at com.glide.script.GlideRecord.postUpdate(GlideRecord.java:5341)
at com.glide.script.GlideRecord.updateWithoutResettingOperation(GlideRecord.java:4869)
at com.glide.script.GlideRecord.update(GlideRecord.java:4736)
at com.glide.script.GlideRecord.update(GlideRecord.java:4655)
at com.snc.process_flow.engine.logic.askforapproval.AFALogic.createApprovalRecords(AFALogic.java:644)
at com.snc.process_flow.engine.logic.askforapproval.AFALogic.afaSetup(AFALogic.java:109)
at com.snc.process_flow.operation.approvals.ApprovalCreateHandler.run(ApprovalCreateHandler.java:27)
at com.snc.process_flow.engine.Operation.execute(Operation.java:207)
at com.snc.process_flow.engine.restricted_caller_access.ExecuteWithCallerAccessTracking.executeWithMetaStack(ExecuteWithCallerAccessTracking.java:21)
at com.snc.process_flow.engine.ProcessEngine.executeOps(ProcessEngine.java:618)
at com.snc.process_flow.engine.ProcessEngine.runInternal(ProcessEngine.java:515)
at com.snc.process_flow.engine.ProcessEngine.run(ProcessEngine.java:502)
at com.snc.process_flow.engine.ProcessEngine.callBlock(ProcessEngine.java:262)
at com.snc.process_flow.engine.CallBlockOperation.callBlock(CallBlockOperation.java:101)
at com.snc.process_flow.engine.CallBlockOperation.run(CallBlockOperation.java:74)
at com.snc.process_flow.engine.Operation.execute(Operation.java:207)
at com.snc.process_flow.engine.restricted_caller_access.ExecuteWithCallerAccessTracking.executeWithMetaStack(ExecuteWithCallerAccessTracking.java:21)
at com.snc.process_flow.engine.ProcessEngine.executeOps(ProcessEngine.java:618)
at com.snc.process_flow.engine.ProcessEngine.runInternal(ProcessEngine.java:515)
at com.snc.process_flow.engine.ProcessEngine.run(ProcessEngine.java:502)
at com.snc.process_flow.engine.ProcessAutomation.run(ProcessAutomation.java:101)
at com.snc.process_flow.engine.GlideProcessAutomation.runSync(GlideProcessAutomation.java:184)
at com.snc.process_flow.engine.GlideProcessAutomation.runWithDomain(GlideProcessAutomation.java:343)
at com.snc.process_flow.engine.GlideProcessAutomation.lambda$runAsUserSync$1(GlideProcessAutomation.java:310)
at com.snc.process_flow.engine.PFSessionClone.run(PFSessionClone.java:71)
at com.snc.process_flow.engine.GlidePFSession.runPlanAsUserSession(GlidePFSession.java:42)
at com.snc.process_flow.engine.GlideProcessAutomation.runAsUserSync(GlideProcessAutomation.java:308)
at com.snc.process_flow.engine.GlideProcessAutomation.messageFlow(GlideProcessAutomation.java:394)
at com.snc.process_flow.engine.GlideProcessAutomation.messageFlow(GlideProcessAutomation.java:373)
at com.snc.process_flow.engine.ProcessHubEventHandler.doSendMessage(ProcessHubEventHandler.java:479)
at com.snc.process_flow.engine.ProcessHubEventHandler.process(ProcessHubEventHandler.java:129)
at com.snc.process_flow.engine.ProcessHubEventHandler.process(ProcessHubEventHandler.java:97)
at com.snc.process_flow.engine.FlowEventManager.processEvents(FlowEventManager.java:168)
at com.glide.job.EventHandlerJob.execute(EventHandlerJob.java:50)
at com.glide.schedule.JobExecutor.lambda$executeJob$0(JobExecutor.java:169)
at com.glide.schedule.JobExecutor.executeJob(JobExecutor.java:172)
at com.glide.schedule.JobExecutor.execute(JobExecutor.java:155)
at com.glide.schedule.JobExecutor.execute(JobExecutor.java:149)
at com.glide.schedule_v2.SchedulerWorkerThread.executeJob(SchedulerWorkerThread.java:449)
at com.glide.schedule_v2.SchedulerWorkerThread.lambda$process$1(SchedulerWorkerThread.java:318)
at com.glide.worker.TransactionalWorkerThread.executeInTransaction(TransactionalWorkerThread.java:35)
at com.glide.schedule_v2.SchedulerWorkerThread.process(SchedulerWorkerThread.java:318)
at com.glide.schedule_v2.SchedulerWorkerThread.run(SchedulerWorkerThread.java:118)
: no thrown error

 

So I also checked Business rule [Approval Events (Task)], and it seems the flow would be called multiple times when the current.state is requested.

approval business rule.png

 

 

 

 

 

 

 

 

I am not sure what triggers recursion since I have checked every part that might be affecting this flow, but nothing suspicious. 

 

Plus, the log I pasted above is not something every time shows up, sometimes it doesn't even generate an error.

 

What I do in this flow:

1. Trigger is when a record is updated under particular conditions. The table is extended from Task table.

Trigger.png

 

 

 

 

 

 

 

 

2. Extract users from a table which is basically the same as looking for users from sys_user table in the Look up record step.

LookUpRecord.png

 

 

 

 

 

 

 

 

3. Loop through the users that are extracted from step 2.

 

4. Do the ask for approval action inside of the loop. The trigger record is the record from step one. Approvers are users from step 2 (Singular in this case since this is inside of the loop).

askForApproval.png

 

 

 

 

 

 

 

 

 

 

 

 

Result:

Approval state is set to cancelled, and state column of sysapproval_approver table is also set to [No longer required]. If I try to change the state into Approved or any other values, it immediately turns back to [No longer required]. 

Activity history also says: No Longer Required was Requested

flowResult.pngsysapproval_approver.png

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I seriously don't know what is causing the error and this behaviour. There aren't many references or solutions for this, which led me here to ask for help.

1 ACCEPTED SOLUTION

The reason of active value changing to false is I didn't set dictionary attribute. If you have to use state column in the child table, which is extended from Task, you have to set dictionary attribute to override its value. When working with the state column in tables extended from the Task table in ServiceNow, it’s crucial to properly configure the dictionary attributes to prevent unexpected behaviour..

View solution in original post

4 REPLIES 4

Amane1
Giga Guru

I have tried to do Ask for approval process even outside of the For each loop, and got the same result. 

I see this behavior when the trigger is [Updated] and the table is extended from Task table.

 

I am hoping this is a bug...

I have found that the state changes to "No longer required" because its active value is being changed to [False]. I don't know what is changing it yet.

The reason of active value changing to false is I didn't set dictionary attribute. If you have to use state column in the child table, which is extended from Task, you have to set dictionary attribute to override its value. When working with the state column in tables extended from the Task table in ServiceNow, it’s crucial to properly configure the dictionary attributes to prevent unexpected behaviour..

Amane1
Giga Guru

In case if the request approval is being inserted endlessly, it may work when run trigger is "Once" not "For every update".