DEV Community

Cover image for Everything you didn't know you needed to know about Power Automate Errors
david wyatt
david wyatt Subscriber

Posted on

5 4 4 4 4

Everything you didn't know you needed to know about Power Automate Errors

The simple truth is all automation/workflow/rpa software is never 100% perfect. Once outside of the platform the risks of issues increase:

  • External system updates
  • Network issues
  • Auth admin updates
  • Too much traffic

just to name a few, will all make your Power Automate flow fail.

So error (or exception handling as I prefer) is key on all of your flows, I have written a blog about how to Exception Handling in Power Automate, and key is not just handling them but getting the why.
Getting the error message is anything but simple (I created a Chrome/Edge extension to make it easier called Power DevBox Exception), so if you want to know how and all of the quirks to getting those error messages, this blog is for you 😎

I'm going to cover:

  1. Why It's Not Simple
  2. Expressions
  3. Expression - actions() Schemas
  4. Expression - result() NonLoops
  5. Expression - result() Loops
  6. Expression - result() Nesting Issues
  7. How to get the message

1. Why It's Not Simple

The honest truth is it probably should be easier, and I hope the Power Automate team focus on this, but the simple truth is its outside of the flow (and mostly the platform). In all cases its a API that fails, and we are limited to how the particular API returns the error message. In theory every API could have a unique schema (name for error, branch of error, detail of error), so trying to have a perfect solution is challenging. Additionally we have to take into account sometimes the API does not want to give a detailed error (security), so its even more challenging.

Outlook Error Schema

{
  "error": {
    "code": "badRequest",
    "message": "Uploaded fragment overlaps with existing data.",
    "innerError": {
      "code": "invalidRange",
      "request-id": "request-id",
      "date": "date-time"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Gmail Error Schema

{
  "error": {
    "code": 400,
    "errors": [
      {
        "domain": "global",
        "location": "orderBy",
        "locationType": "parameter",
        "message": "Sorting is not supported for queries with fullText terms. Results are always in descending relevance order.",
        "reason": "badRequest"
      }
    ],
    "message": "Sorting is not supported for queries with fullText terms. Results are always in descending relevance order."
  }
}
Enter fullscreen mode Exit fullscreen mode

2. The Expressions

To get the error message we use 3 different expressions:

  • outputs() - For none stand actions (not Compose/Select)
  • actions() - For all actions (includes outputs as child key)
  • result() - For container (e.g Scope/Condition/Do_Until)

Actions()/outputs() should be targeted at a specific action, and result() at a container, returning any actions error from within it.

The 3 are actually just levels, with outputs() inside actions(), and actions() inside result(), so for safety actions() is a better choice then outputs() instead of actions() for single actions.

schema nests

These expressions are not designed specifically for error messages, they just what the API returns (don't forget containers are still API's, they are just internal API's specifically for Power Automate, but not part of Power Automate). So we would not get just the error message like on my Outlook and Gmail examples, but a values even if successful.

3. Expression - actions() Schemas

The actions() schema includes key information and if it was Successful, Failed, Timedout, Skipped. The array has the following standard keys within it:

  • name - action name
  • inputs* - (action inputs)
  • outputs* - (response)
  • startTime - (when called)
  • endTime - (when responded)
  • trackingId
  • clientTrackingId
  • clientKeywords
  • code - (error type like BadRequest)
  • status - ( Successful, Failed, Timedout, Skipped)

* Not always, see Root Error

As you can imagine the inputs are specific to the action, and the outputs are too. So far I have found 3 main output schemas for getting the actions() error message.

Roor Error

This is in the item, and replaces both the inputs and outputs:

"error": {
      "code": "InvalidTemplate",
      "message": "Unable to process template language expressions in action 'Compose' inputs at line '0' and column '0': 'The template language function 'int' was invoked with a parameter that is not valid. The value cannot be converted to the target type.'."
    }
Enter fullscreen mode Exit fullscreen mode

actions()?['error']?['message']

Outputs Body Error

The Body Error is in the Outputs key:

"body": {
        "error": {
          "code": "0x80060888",
          "message": "Resource not found for the segment 'testError'."
        }
      }
Enter fullscreen mode Exit fullscreen mode

Also is some error response there is a 'innerError', which messages what group the error is in

actions()?['outputs']?['body']?['error']?['message']

actions error response

Outputs Body

Finally there is the no error schema, where the message is just returned in the body:

"body": {
        "message": "SharePoint Site Address 'testError' is not valid\r\nclientRequestId: 93d8e56a-5940-454a-9b8c-226eacf793f1",
        "fromPolicy": true
      }
Enter fullscreen mode Exit fullscreen mode

actions()?['outputs']?['body']?['message']

But just to extra confuse you, there are also the combined, where it is both Outputs Body Error and Outputs Body.

"body": {
        "status": 400,
        "message": "The provided drive id appears to be malformed, or does not represent a valid drive.\r\nclientRequestId: 70b08565-a541-4891-9609-b3b0be39fbbb\r\nserviceRequestId: c6a84050-69c1-4b5d-94d9-8d673c1707f3",
        "error": {
          "message": "The provided drive id appears to be malformed, or does not represent a valid drive."
        },
        "source": "excelonline-ncus.azconn-ncus-001.p.azurewebsites.net"
      }
Enter fullscreen mode Exit fullscreen mode

Who Uses What

I did some testing, and I really struggled to find any sort of pattern. I did find these few rules:

  • Standard actions (Compose/Select/Set Variable) are all Roor Error
  • None Microsoft always seem to use Outputs Body Error

Check out this table to make sense of it.

name type Type root outputsBody outputsBodyError
Compose_2 - root {"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'Compose_2' inputs at line '0' and column '0': 'The template language function 'int' was invoked with a parameter that is not valid. The value cannot be converted to the target type.'."}
Get_items_2 GET outputsBody SharePoint Site Address 'testError' is not valid clientRequestId: 93d8e56a-5940-454a-9b8c-226eacf793f1
Create_item_2 POST outputsBody SharePoint Site Address 'testError' is not valid clientRequestId: e4eea714-ace5-4f10-b337-88015e71395b
List_rows_2 GET outputsBodyError {"code":"0x80060888","message":"Resource not found for the segment 'testError'."}
Add_a_new_row_2 POST outputsBodyError {"code":"0x80060888","message":"Resource not found for the segment 'testError'."}
Get_emails_(V3) GET outputsBody Specified folder 'testError' does not exist. clientRequestId: b5b3b4ef-defd-48c4-9f32-1bdcffc3b575 serviceRequestId: 9bf3816a-e679-42ce-85ba-486949e98683
Send_an_email_(V2) POST root {"code":"OpenApiOperationParameterTypeConversionFailed","message":"The 'inputs.parameters' of workflow operation 'Send_an_email_(V2)' of type 'OpenApiConnection' is not valid. Error details: Input parameter 'emailMessage/To' is required to be of type 'String/email'. The runtime value '\"testError\"' to be converted doesn't have the expected format 'string/email'."}
Get_messages_ GET outputsBodyError {"code":"BadRequest","message":"teamId needs to be a valid GUID.","innerError":{"date":"2025-03-09T21:15:19","request-id":"5c20a154-635b-4045-9c5c-71bd5da30969","client-request-id":"5c20a154-635b-4045-9c5c-71bd5da30969"}}
Create_a_Teams_meeting POST root {"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'Create_a_Teams_meeting' inputs at line '0' and column '0': 'The template language function 'uriPath' must have only one parameter.'."}
Get_tables GET bothOutputs The provided drive id appears to be malformed, or does not represent a valid drive. clientRequestId: 70b08565-a541-4891-9609-b3b0be39fbbb serviceRequestId: c6a84050-69c1-4b5d-94d9-8d673c1707f3 {"message":"The provided drive id appears to be malformed, or does not represent a valid drive."}
Add_a_row_into_a_table POST outputsBodyError {"code":"","message":"The request entity's media type 'text/plain' is not supported for this resource."}
JSON_(V2) POST outputsBodyError {"code":401,"source":"49798dfe-da17-e59d-9574-009769d1f502.03.common.usa002.azure-apihub.net","clientRequestId":"668dc82e-ab3d-4741-ad19-99d5f92657b0","message":"The response is not in a JSON format.","innerError":"Unauthorized"}

Highlights

SharePoint:outputsBody
Dataverse: outputsBodyError
Outlook GET: outputsBody
Outlook POST: root
Teams GET: outputsBodyError
Teams POST: root
Excel GET: bothOutputs
Excel POST: outputsBodyError

4. Expression - result() NonLoops

For Conditions/Switches/Scopes the result() expression returns an array of all actions within the container, and it uses the actions() schema, just in an array.

results error response

So now the 3 different schemas can be read with:

result()[]?['error']?['message']
result()[]?['outputs']?['body']?['error']?['message']
result()[]?['outputs']?['body']?['message']

result and actions

5. Expression - result() Loops

For Apply To Each/Do Untils the keys are the same, except an addition array for each iteration structure. So:

Non Loops = ArrayItems[item]
Loops = ArrayItems[ArrayIteration[Item]]

There is an extra key added called outputs, which is the array of iterations, so its not: iteration array - action array, its action array - iteration array.

[
  {
    "name": "Create_item_loop",
    "outputs": [
      {
        "name": "Create_item_loop",
        "inputs": {
          "host": {
            "apiId": "subscriptions/0188c127-faf9-4368-8612-930f6e518355/providers/Microsoft.Web/locations/westus/runtimes/unitedstates-002/apis/sharepointonline",
            "connectionReferenceName": "shared_sharepointonline",
            "operationId": "PostItem"
          },
          "parameters": {
            "dataset": "testError",
            "table": "error",
            "item": {}
          }
        },
        "outputs": {
          "statusCode": 400,
          "headers": {
            "Date": "Sun, 09 Mar 2025 22:07:39 GMT",
            "Content-Length": "149",
            "Content-Type": "application/json"
          },
          "body": {
            "message": "SharePoint Site Address 'testError' is not valid\r\nclientRequestId: 069fae52-8817-4cdc-90c8-607b4e15fa0b",
            "fromPolicy": true
          }
        },
        "startTime": "2025-03-09T22:07:39.8181209Z",
        "endTime": "2025-03-09T22:07:39.8421147Z",
        "trackingId": "8cde7fb4-5a18-4abe-a4b5-6ac39d4ebac7",
        "clientTrackingId": "08584600488260423008959204859CU179",
        "clientKeywords": [
          "testFlow"
        ],
        "code": "BadRequest",
        "status": "Failed"
      },
      {
        "name": "Create_item_loop",
        "inputs": {
          "host": {
            "apiId": "subscriptions/0188c127-faf9-4368-8612-930f6e518355/providers/Microsoft.Web/locations/westus/runtimes/unitedstates-002/apis/sharepointonline",
            "connectionReferenceName": "shared_sharepointonline",
            "operationId": "PostItem"
          },
          "parameters": {
            "dataset": "testError",
            "table": "error",
            "item": {}
          }
        },
        "outputs": {
          "statusCode": 400,
          "headers": {
            "Date": "Sun, 09 Mar 2025 22:07:39 GMT",
            "Content-Length": "149",
            "Content-Type": "application/json"
          },
          "body": {
            "message": "SharePoint Site Address 'testError' is not valid\r\nclientRequestId: 2279b3bd-0cd5-4979-9089-830b11a7f6a7",
            "fromPolicy": true
          }
        },
        "startTime": "2025-03-09T22:07:40.0288804Z",
        "endTime": "2025-03-09T22:07:40.0523401Z",
        "trackingId": "4c7ad101-2ab0-445b-b2f9-0d3b68a17b20",
        "clientTrackingId": "08584600488260423008959204859CU179",
        "clientKeywords": [
          "testFlow"
        ],
        "code": "BadRequest",
        "status": "Failed"
      }
    ],
    "startTime": "2025-03-09T22:07:41.1066983Z",
    "endTime": "2025-03-09T22:07:41.1774793Z",
    "trackingId": "e371c464-64f3-4b9e-bf4e-02c9ebc86503",
    "clientTrackingId": "08584600488260423008959204859CU179",
    "clientKeywords": [
      "testFlow"
    ],
    "code": "NotSpecified",
    "status": "Failed",
    "repetitionCount": 2
  }
]
Enter fullscreen mode Exit fullscreen mode

6. Expression - result() Nesting Issues

An important call out to be made with result(), and that is it is only one level deep. So if you have containers within containers you won't read the error message. The error bubbles up, so the container fails with the message "An action failed. No dependent actions succeeded." using root schema.

Additionally you can't reference a container within a loop that contains a loop. I know I'm confused to, but let's say there is a condition within a loop and it has a loop inside it. You can't use result() on that condition. But you can reference:

  • A Loop with a non loop container
  • A non loop container with a loop container
  • A loop with a loop container
  • A loop within a loop container

nesting error

7. How to get the message

There are a few ways to get the error message, first call out is the using the result() is the best as you can target one container and catch every error (instead of expression for each action).

The way I recommend is to get the first of each of the error types and wrap in a coalesce (a coalesce returns the first none null item):

coalesce(
    result('yourContainerName')[0]?['error']?['message']
,
    result('yourContainerName')[0]?['outputs']?['body']?['error']?['message']
,
    result('yourContainerName')[0]?['outputs']?['body']?['message']
)
Enter fullscreen mode Exit fullscreen mode

We use the [0] to get the first action that fails from the result() array.

If you are targeting an array remember it's a little different, first you have to filter the result array to get the failed action

coalesce(
    body('Filter_array')[0]?['outputs'][0]?['error']?['message']
,
    body('Filter_array')[0]?['outputs'][0]?['outputs']?['body']?['error']?['message']
,
    body('Filter_array')[0]?['outputs'][0]?['outputs']?['body']?['message']
)
Enter fullscreen mode Exit fullscreen mode

loop filter error

The second way is cooler but more complex, and that's to use xpath. We convert the json to XML and then use xpath to filter and return the error messages. Below will return error message for 2 scopes:

xpath(
  xml(json(concat(
    '{"data": {'
  ,
    '"Scope1":'
  ,
    result('Scope1')
  ,
    ','
  ,
    '"Scope2":'
  ,
    result('Scope2')
    ','
  ,
   '}}'
  )))
 ,
   'string(//message[not(contains(.,''The execution of template action'')) and not(contains(.,''skipped:''))  and not(contains(.,''An action failed. No dependent actions succeeded.''))])'
)
Enter fullscreen mode Exit fullscreen mode

The expression creates a object called 'data' with all of the result() arrays, it then filters the combined array return:

  • All Keys named: message
  • That does not contain 'The execution of template action'
  • That does not contain 'skipped'
  • That does not contain 'An action failed. No dependent actions succeeded.'

As you can see the xpath is neater, but more complex.


As you can see, it's a bit of a rabbit hole, and there is definitely stuff I have missed (and probably got wrong), but hopefully you will now understand how exceptions can be found and extracted.

I've uploaded the flow I used to test and learn here named Exception Generator


If you would like to get notified every new blog (I also do a few in the Power Platform Community), subscribe below

Top comments (2)

Collapse
 
veilgen_ profile image
Veilgen Security •

Great breakdown of Power Automate error handling! The explanation of different error schemas and how APIs return errors in various formats is particularly useful. The deep dive into expressions like actions(), outputs(), and result() provides a solid foundation for troubleshooting automation flows efficiently. Looking forward to trying out the Power DevBox Exception extension—seems like a game-changer for debugging! Thanks for sharing these insights.

Collapse
 
balagmadhu profile image
Bala Madhusoodhanan •

Amazing insightful article @wyattdave