“I’d like to update document properties in my Power Automate approval flow, but the flow creates duplicate task with each update.”
I already wrote a post how to avoid infinite trigger loop. But recently I realized there might be one more way to block multiple flow runs. It’s useful especially for approval processes in Power Automate as a way to avoid duplicate tasks. The option to have a separate service account is still the best one, but not everyone has access to one.
This approach is a combination of a trigger condition and an action ‘Get changes for an item or a file’. And you can do it with your personal account.
You’ve got a flow with trigger on document update. When user updates a file, the approval process will start. Flow sets ‘Approval status’ to ‘In approval’ and assigns a task. Here you encounter the first problem: document property is updated and the flow starts again. Over and over again, approver is getting one task after another.
Important: the library must have version history enabled.
Trigger condition (during process)
It’s quite simple to block running another flow during the approval process. There’s the ‘Approval status’ column, that has value ‘In approval’ only if the process is running. Simple trigger condition will solve this. Run the flow only if ‘Approval status’ is not ‘In approval’.
@not(equals(triggerOutputs()?['body/ApprovalStatus/Value'], 'In approval'))
Get changes for an item or a file (after process)
The tricky part starts with the last update. The flow updates the document property to ‘Approved’ or ‘Rejected’. That’s another update that will start the flow. But in this case you can’t block it using the trigger condition. The flow can’t start on update by the flow (the process would start over again), but it must start on another user update. In both of the cases the document will have status ‘Approved’ or ‘Rejected’. So, how to decide who did the last update?
That’s when the action ‘Get changes for an item or a file’ will find its use, it’ll give you information which fields were updated. It won’t give you the old/new values in the fields, just a true/false information if column was updated. But that’s enough, since you’ll care only about the columns updated by the flow.
The idea is that the column ‘Approval status’ is updated only by the flow. If you check the previous version of the document and you see the ‘Approval status’ was changed, you can deduce the last update was done by the flow – don’t start it again. If ‘Approval status’ wasn’t changed in the previous version, it was updated by the user – start the flow.
To get the previous version of the document, use expression in the format below. It’ll take the version number from the trigger, convert it to integer and decrease it by 1.
All that’s left is a condition to stop the flow if it was updated by another instance of the flow. If the ‘Has Column Changed: ApprovalStatus’ is equal ‘true’, terminate the flow.
In this solution you got 2 situations, update during approval process and update after approval is completed. During approval process the trigger condition is just fine, and you can block any new instances of the flow. More complicated situation is at the end, when you can’t just block all runs. In such a case one more run of the flow is inevitable. But it’s just one more and then stop.
It’s good to think about the flows as a complex solutions. There might be not a single solution that will handle all situations, but there are multiple possibilities, you just need to put them all together. If you can solve situation directly in the trigger condition, it’s great. But if not, maybe there’s a solution later in the flow, when you’ve got much more possibilities.