Cancel more than 20 running flows at a time in Power Automate

Cancel All Flow Runs Using Power Automate More Than 20 Flows

No comments

Loading

In this “Cancel All Flow Runs Using Power Automate” article, we will learn about how to cancel all flow runs using Power Automate from a given environment or all instances of a particular flow dynamically. Before getting into the article, let’s understand what challenges we face while trying to cancel more than 20 instances of the same flow.

Business use cases: Cancel All Flow Runs Using Power Automate

Let’s say you have a product list or document library in SharePoint Online, and there is an automated flow associated with it that triggers when an item is created or modified in the SharePoint Online list or document library. The admin user adds products manually or through some automation process. When the admin user adds a product manually, one by one, the background flow triggers and completes as usual. But if the admin user creates multiple product items through some automated batch or third-party application, at that time multiple instances of the same flow will start triggering at a time.

As a result, all flow instances will be in a running state for hours, which will impact tenant-level resource usage. So, in this scenario, we need to cancel these flow-running instances. We can cancel these flow-running instances using the flow-run history Power Automate page, but it will not allow us to select more than 20 flow-running instances at a time. This will become a bottleneck for the admin person to manage these flow runs. Yes, we can cancel using the out-of-the box flow run history page at a time when 20 flows run instances, but this will take a lot of time.

This is just one of the use cases; likewise, there can be many business scenarios.

Challenges in Flow Cancel: Power Automate Flow Run Limits (20)

We have a test that could automate flow where we have internationally started 40 instances of this flow and are trying to cancel all run instances of this flow.

To do that, we go to my “My Flows” gallery and select my test flow, then click on the “Run History” flow menu.

 

Get Flow Run History in Power Automate
Get Flow Run History in Power Automate

Once we get into the flow “Run history” page, we will select more than 20 run instances of the flow, and then we will get this error: “You can only resubmit up to 20 and cancel up to 20 flow runs at a time,” which means we can resubmit (resubmit flow Power Automate) or cancel more than 20 flows at a time.

You can only resubmit up to 20 and cancel up to 20 flow runs at a time.
You can only resubmit up to 20 and cancel up to 20 flow runs at a time.

So if we want to cancel all flow run instances, we need to cancel in batches of each 20 selections. In this case, if you have hundreds of flow run instances, canceling all flow run instances will take plenty of time. So this becomes a bottleneck for managing the flow. That is where flow management automation comes in. Using the Power Automate flow, we can cancel all instances of the flow. Let’s go to the next section to achieve that.

Cancel All Flow Runs Using Power Automate More Than 20 Flows

This is my manual-triggered flow, which I triggered manually.

Cancel All Flow Runs Using Power Automate – Demo

This is the complete executed flow.

Cancel All Flow Runs Using Power Automate More Than 20 Flows
Cancel All Flow Runs Using Power Automate More Than 20 Flows

Once this flow is completed, we can see that all running flows have been cancelled.

Note:

  • This flow takes sometimes (depending on the number of flows running at the current time) to complete its execution; in this screenshot, though it is in running mode, it has cancelled all running flows (shown below).
Cancel All Flow Runs Using Power Automate More Than 20 Flows Demo
Cancel All Flow Runs Using Power Automate More Than 20 Flows Demo

Cancel All Flow Runs Using Power Automate: Flow Explanation

Create a manually triggered flow and add a “List Flows as Admin (V2)” action.

List Flows as Admin (V2) - Get all flows from an Power Platform Environment
List Flows as Admin (V2) – Get all flows from an Power Platform Environment

Select your Power Platform Environment from where you want to get all flows.

Add a data operation compose action to find the length of the “List Flows as Admin (V2)” get all flows result.

Length of List Flows as Admin (V2) - Get all flows from an Power Platform Environment
Length of List Flows as Admin (V2) – Get all flows from an Power Platform Environment

Create the below three string variables:

  • varStrRunningFlowEnvironment: It stores the current running flow environment.
  • varStrRunningFlowID: It stores the current running flow ID.
  • varStrRunningFlowRunID: It stores the current running flow run ID.
Create string type 3 variables in Power Automate
Create string type 3 variables in Power Automate

Notes:

  • In the above three variables, you can pass the default value for environment ID, flow ID, and flow run ID. From here, you can get the environment ID, flow ID, and flow run ID. If you pass the hard-coded environment, flow, and run ID, you will be able to cancel only for a selected flow. However, if you want to dynamically cancel all running flows from your environment, you need to keep these values empty and get them dynamically using the string functions of Power Automate.
  • In this demo, we have kept these values empty and handled them dynamically using the Power Automate string functions.

Add an “Apply to each” control to loop through all flows.

In the “select and output from previous steps” section, pass the “Value” parameter from the “List Flows as Admin (V2)” action output or the below value directly:

@{outputs('List_Flows_as_Admin_(V2)_|_GetAllFlowsFromEnvironment')?['body/value']}
Apply to each control to loop through each flows from the Power Platform Environment
Apply to each control to loop through each flows from the Power Platform Environment

Inside “foreach each loop”, add an “Invoke an HTTP request” action (premium connector; learn how to work with the premium connector in Power Automate) to get all running flows where you configure the below parameters:

  • Method: Get
  • Url of the request: See below:
https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/@{items('Apply_to_each_|_Loop_through_all_the_flows')?['properties/environment/name']}/flows/@{items('Apply_to_each_|_Loop_through_all_the_flows')?['name']}/runs?api-version=2016-11-01&$filter=Status%20eq%20%27running%27
Invoke an HTTP request configuration to get all running flows
Invoke an HTTP request configuration to get all running flows

 

By this time, you should have at least one long running flow in your environment, and you need to copy the output of the “Invoke an HTTP request | Get all running flows” action. It should be like below:

{
"value": [
{
"name": "08585036505089512937996483890CU16",
"id": "/providers/Microsoft.ProcessSimple/environments/Default-f10e1e03-fffa-47d0-86f4-d0e3c317c65d/flows/63351b1a-b72c-4abe-b0b8-023f60ad9e2b/runs/08585036505089512937996483890CU16",
"type": "Microsoft.ProcessSimple/environments/flows/runs",
"properties": {
"startTime": "2023-10-22T06:32:56.5335605Z",
"status": "Running",
"correlation": {
"clientTrackingId": "08585050023933356130358578702CU82",
"clientKeywords": [
"resubmitFlow"
]
},
"trigger": {
"name": "When_an_item_is_created_or_modified",
"inputsLink": {
"uri": "https://prod-16.westus.logic.azure.com:443/workflows/46df992d7f1e4dd8940d639a5f886ae3/runs/08585036505089512937996483890CU16/contents/TriggerInputs?api-version=2016-06-01&se=2023-10-22T11%3A00%3A00.0000000Z&sp=%2Fruns%2F08585036505089512937996483890CU16%2Fcontents%2FTriggerInputs%2Fread&sv=1.0&sig=rgf6J19gw68nmwRCm9dmCpDEOteROPZdCtbtZ3L6M4M",
"contentVersion": "C9ambHQhhZ0aXilLeat4XQ==",
"contentSize": 349,
"contentHash": {
"algorithm": "md5",
"value": "C9ambHQhhZ0aXilLeat4XQ=="
}
},
"outputsLink": {
"uri": "https://prod-16.westus.logic.azure.com:443/workflows/46df992d7f1e4dd8940d639a5f886ae3/runs/08585036505089512937996483890CU16/contents/TriggerOutputs?api-version=2016-06-01&se=2023-10-22T11%3A00%3A00.0000000Z&sp=%2Fruns%2F08585036505089512937996483890CU16%2Fcontents%2FTriggerOutputs%2Fread&sv=1.0&sig=gyA-QULEBtXniTtDsuhMPC5-nuQ28CFISlr4LKMk8MI",
"contentVersion": "qXYgpp7IgTQVhvdtkYx5ZA==",
"contentSize": 3889,
"contentHash": {
"algorithm": "md5",
"value": "qXYgpp7IgTQVhvdtkYx5ZA=="
}
},
"startTime": "2023-10-22T06:32:56.5188019Z",
"endTime": "2023-10-22T06:32:56.5188019Z",
"originHistoryName": "08585050023933356130358578702CU82",
"sourceHistoryName": "08585036535167138541551593526CU136",
"correlation": {
"clientTrackingId": "08585050023933356130358578702CU82",
"clientKeywords": [
"resubmitFlow"
]
},
"status": "Succeeded"
}
}
}
]
}

Add a Parse JSON action to parse and get all running flow results. In the content, pass the “body” from “Invoke an HTTP request | Get all running flows“.

And in the schema section, pass the generated schema from the sample schema.

Add a Parse JSON action to parse get all running flows result
Add a Parse JSON action to parse get all running flows result

Add a compose data operation action to find the length of “Parse JSON | Get all running flows”.

length(body('Parse_JSON_|_Get_all_running_flows')?['value'])
Add a compose data operation action to find the length of Parse JSON Get all running flows
Add a compose data operation action to find the length of Parse JSON Get all running flows

Add an “if” condition to check whether the get all running flows outcome length is greater than 0. If it is yes, then the flow is in a running state.

length(body('Parse_JSON_|_Get_all_running_flows')?['value'])
Add an If condition to check whether the get all running flows outcome length greater than 0
Add an If condition to check whether the get all running flows outcome length greater than 0

In the “Yes” section, add an “Apply each” control to loop through the “Parse JSON | Get all running flows” output.

In the “Select an output from steps” box, pass the below value or select the value property from the “Parse JSON | Get all running flows” output:

@{body('Parse_JSON_|_Get_all_running_flows')?['value']}
Add an Apply each control to loop through the Parse JSON Get all running flows
Add an Apply each control to loop through the Parse JSON Get all running flows

Inside the apply to each loop, add a compose option to get the “id” property from the “Parse JSON | Get all running flows” output. To do that, you can directly select the “id” property from the “Parse JSON | Get all running flows” output, or you can pass the below value directly:

@{items('Apply_to_each')?['id']}

Note:

  • This “id” is the key property from the parsed JSON output (shown below). From this string, we will extract the environment ID, flow ID, and flow run ID to cancel the flow runs.
"id": "/providers/Microsoft.ProcessSimple/environments/Default-f10e1e03-fffa-47d0-86f4-d0e3c317c65d/flows/63351b1a-b72c-4abe-b0b8-023f60ad9e2b/runs/08585036505089512937996483890CU16",

Get Environment ID from the Running Flow Dynamically

To get the environment ID dynamically, we need to perform a couple of data operations. Add three compose data operations and pass the value as shown below:

To get the source index “/environments/” from the above “ID” property, use the below nthindexOf function expression:

@{nthIndexOf(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'), '/environments/', 1)}

 

To get the target index “/flows/” from the above “ID” property, use the below nthindexOf function expression:

 

@{nthindexOf(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'), '/flows/', 1)}

 

To find the length between the “/flows/” and “/environments/” indexes, use the below sub function expression:

@{sub(outputs('Compose_-_Compose_–_Get_To_target_index_(Flows_index)'),outputs('Compose_–_Get_From_source_index_(Environments_index)'))}

Compose action to calculate substring in Power Automate
Compose action to calculate substring in Power Automate

Get Environment ID from the flow Run URL

To extract the Environment ID from the flow run URL, use the below substring function expression:

@{substring(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'),add(outputs('Compose_–_Get_From_source_index_(Environments_index)'),14),sub(outputs('Length_between_To_and_From_Index_(flows)_and_environments)'),14))}
Get Environment ID from the flow Run URL using substring function
Get Environment ID from the flow Run URL using substring function

 

The above substring function will extract the “Default-f10e1e03-fffa-47d0-86f4-d0e3c317c65d” from this “ID” property: “/providers/Microsoft.ProcessSimple/environments/Default-f10e1e03-fffa-47d0-86f4-d0e3c317c65d/flows/63351b1a-b72c-4abe-b0b8-023f60ad9e2b/runs/08585036505089512937996483890CU16”

Get the flow ID from the running flow dynamically.

To get the flow ID from the running flow dynamically, we need to follow the same techniques as the above environment ID. Here we need to find the index position of the “/flows/” and “/runs/” indexes and extract the text between these two indexes. Let’s add three compose data operation actions and add the expression value as shown below:

Compose – Get From source index (Flows index):

nthIndexOf(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'),'/flows/',1)
Get substring source index using the nthIndexOf function in Power Automate
Get substring source index using the nthIndexOf function in Power Automate

Compose – Get To target index (Runs index):

nthIndexOf(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'), '/runs/', 1)
Get substring target index using the nthIndexOf function in Power Automate
Get substring target index using the nthIndexOf function in Power Automate

Compose – Difference in To and From Index (Between Runs and Flows):

sub(outputs('Compose_–_Get_To_target_index_(Runs_index)'),outputs('Compose_–_Get_From_source_index_(Flows_index)'))
Get difference between source and target index using the nthIndexOf function in Power Automate
Get difference between source and target index using the nthIndexOf function in Power Automate

Get the flow ID from the flow run URL.

To get the flow ID from the flow run URL, use the below substring function:

substring(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'),add(outputs('Compose_–_Get_From_source_index_(Flows_index)'),7),sub(outputs('Compose_-_Difference_in_To_and_From_Index_(Between_Runs_and_Flows)'),7))
Get Flow ID from the flow Run URL dynamically
Get Flow ID from the flow Run URL dynamically

Get the flow run ID from the flow run URL

To get the flow run ID from the flow run URL, use the below lastindexOf function inside the substring:

@{substring(outputs('Compose_-_Get_ID_from_Get_All_Running_Flows_API'),add(outputs('Compose_–_Get_From_source_index_(Flows_index)'),7),sub(outputs('Compose_-_Difference_in_To_and_From_Index_(Between_Runs_and_Flows)'),7))}

Get Flow Run ID from the flow Run URL Dynamically using the lastindexOf function

Get Flow Run ID from the flow Run URL Dynamically using the lastindexOf function

Note:

  • In the above, we have shown the compose data operation action to store the environment and flow ID value, but the same value we can store in the variable as well. Here, we have used both variable and compose, but we have only shown the compose operation screenshot to store the environment ID and flow ID.

Using Cancel Flow Run Action Cancel Flow Run

To perform the cancel flow runs, add a cancel flow run action from the Power Automate Management section where you pass the environment ID, flow ID, and flow run ID variables, like below:

Cancel flow run action in Power Automate
Cancel flow run action in Power Automate

Cancel Flow Run using the REST API

As an alternative, we can cancel the flow run using the below REST API as well:

API Endpoint to List Flow Runs:

Method: GET 

https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}/runs?api-version=2016-11-01

API Endpoint to Cancel a Flow Run:

Method: POST 

https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/{FlowEnvironment}/flows/{FlowGUID}/triggers/manual/histories/{FlowRunID}/cancel?api-version=2016-11-01

Note:

Formula to substract in between text from the “From” and “To” index locations

In this article, we have played around with the nthIndexOf and substring functions of Power Automate. The easiest way to remember this formula is as below:

substring('Your main string', position of source index, length between 'To' and 'From' index)

Cancel All Flows Runs Using Power Automate: Complete Screenshot

Below are the complete screenshots of the flow:

Cancel all flows running using Power Automate Flow Part 1

Cancel all flows running using Power Automate Flow Part 2

Cancel all flows running using Power Automate Flow Part 3

Cancel all flows running using Power Automate Flow Part 4

Cancel all flows running using Power Automate Flow Part 5

Cancel all flows running using Power Automate Flow Part 6

Cancel all flows running using Power Automate Flow Part 7

Cancel all flows running using Power Automate Flow Part 8

Cancel all flows running using Power Automate Flow Part 9

Cancel all flows running using Power Automate Flow Part 10
Cancel all flows running using Power Automate Flow

 

Summary: Cancel All Flow Runs using Power Automate

Thus, in this article, we have learned about how to cancel multiple flow run instances using the Power Automate Cancel Flow Run action and REST API call. Generally, we can cancel or resubmit 20 flow run instances at a time, but using Power Automate flow cancel, we can cancel unlimited flow run instances. In this article, we have also learned how to work with Power Automate string functions like indexOf(), lastIndexOf(), nthIndexOf(), substring(), sub(), add(), etc.

See Also: Power Platform Articles

You may also visit the Power Platform article hub, where you will see a bunch of articles focusing on Power Platform, like Power Automate, Power Apps, etc. All the articles are written with real-time project scenarios and troubleshooting techniques. For the Power Automate function references, you may refer to this Microsoft Power Automate Function references  article.

 

About Post Author

Do you have a better solution or question on this topic? Please leave a comment