Introduction
Power Automate makes it easy to automate business processes, but building a flow is only one part of the solution.
When a flow is running in a production environment, failures are inevitable. A SharePoint action may fail, an API may return an error, an email address may be invalid, or a connector may temporarily become unavailable.
The real challenge is not only detecting that the flow failed.
The challenge is:
How do we know what failed, why it failed, which flow run was affected, and how can the support team quickly investigate it?
In this article, we will build a reusable error-handling framework using Power Automate.
The framework will capture:
Flow Name
Flow Run ID
Flow URL
Failed Action
Status Code
Error Message
Failure Timestamp
Environment
It will then generate a professional HTML email notification for the support team.
What We Are Building
Our final solution will follow a Try-Catch-Finally pattern.
Trigger
↓
TRY Scope
↓
Business Process
↓
Success ───────────→ Continue
↓
Failure / Timeout
↓
CATCH Scope
↓
Identify Failed Action
↓
Capture Error Details
↓
Build Error Object
↓
Generate HTML Email
↓
Send Error Notification

Business Scenario
For this demonstration, we will create an employee onboarding flow.
Whenever a new employee is added to a SharePoint list, Power Automate will:
Get the employee details.
Create an onboarding folder.
Send a welcome email.
The normal process looks like:
New Employee
↓
Get Employee Details
↓
Create Onboarding Folder
↓
Send Welcome Email
If any action fails, our error handler will automatically capture the failure.
Prerequisites
For this example, you need:
Microsoft SharePoint
Power Automate
Office 365 Outlook
Access to create cloud flows
A SharePoint site
A SharePoint list
A SharePoint document library
Step 1 — Create the SharePoint List
Create a SharePoint list named:
Employee Onboarding
Create the following columns:
| Column | Type |
|---|---|
| Title | Single line of text |
| Employee Email | Single line of text |
| Department | Single line of text |
| Joining Date | Date and Time |
| Onboarding Status | Choice |
For Onboarding Status, create:
Pending
Processing
Completed
Failed

Step 2 — Create the Automated Flow
Create an Automated cloud flow.
Use the following name:
Employee Onboarding - Error Handling Demo
For the trigger, select:
SharePoint – When an item is created
Configure:
Site Address:
Your SharePoint Site
List Name:
Employee Onboarding
Step 3 — Rename the Trigger
Rename the trigger to:
TRG_New_EmployeeUsing meaningful action names is important when creating an error-handling framework because these names will later appear in our error notification.
Instead of:
When an item is createdwe use:
TRG_New_Employee
Step 4 — Create the TRY Scope
Add:
Control → Scope
Rename it:
TRY_Process_EmployeeThis scope will contain our main business logic.
The structure will be:
TRY_Process_Employee
│
├── Get_Employee_Details
├── Create_Onboarding_Folder
└── Send_Welcome_Email
Step 5 — Get Employee Details
Inside the TRY scope, add:
SharePoint → Get item
Rename:
Get_Employee_DetailsConfigure:
Site Address:
Your SharePoint Site
List Name:
Employee Onboarding
Id:
ID from TRG_New_EmployeeThis action retrieves the complete employee record.

Step 6 — Create the Employee Folder
Add:
SharePoint → Create new folder
Rename:
Create_Onboarding_FolderConfigure:
Site Address:
Your SharePoint Site
List or Library:
EmployeeDocumentFor the folder path, we use:
Employees/@{outputs('Get_Employee_Details')?['body/Title']}For example:
Employees/Ismail Sayyad
Step 7 — Send the Welcome Email
Add:
Office 365 Outlook → Send an email (V2)
Rename:
Send_Welcome_EmailExample configuration:
To:
Employee Email
Subject:
Welcome to the TeamBody:
Hello,
Welcome to the team!
Your employee onboarding process has been initiated successfully.
Regards,
HR Team
Step 8 — Test the TRY Scope
Before implementing error handling, test the normal scenario.
Create an employee:
Employee Name:
Ismail Sayyad
Employee Email:
[email protected]
Department:
IT
Joining Date:
25-Aug-2026The flow should execute successfully:
TRG_New_Employee ✅
↓
Get_Employee_Details ✅
↓
Create_Onboarding_Folder ✅
↓
Send_Welcome_Email ✅
Step 9 — Create the CATCH Scope
Now we will implement the error-handling framework.
Outside the TRY scope, add:
Control → Scope
Rename:
CATCH_Error_HandlerThe flow now contains:
TRY_Process_Employee
CATCH_Error_Handler
Step 10 — Configure Run After
Open the three-dot menu on:
CATCH_Error_HandlerSelect:
Configure run after
Enable:
☑ has failed
☑ has timed outLeave the other options unchecked for this example.
This means:
TRY succeeds
↓
CATCH doesn't execute
TRY fails
↓
CATCH executes
TRY times out
↓
CATCH executes
Step 11 — Get Failed Actions
Inside the CATCH scope, add:
Data Operation → Filter array
Rename:
Filter_Failed_ActionsFor From, use:
result('TRY_Process_Employee')Then use advanced mode:
@equals(item()?['status'], 'Failed')This filters the actions inside our TRY scope and keeps only failed actions.

Step 12 — Get the Failed Action Name
Add:
Data Operation → Compose
Rename:
Compose_Failed_ActionUse:
if(
greater(length(body('Filter_Failed_Actions')), 0),
first(body('Filter_Failed_Actions'))?['name'],
'Unknown'
)If:
Create_Onboarding_Folderfails, the Compose action returns:
Create_Onboarding_Folder
Step 13 — Capture the Error Message
Add another Compose:
Compose_Error_MessageUse:
first(
split(
first(body('Filter_Failed_Actions'))?['outputs']?['body']?['message'],
'clientRequestId:'
)
)This extracts the useful error message while removing technical identifiers such as:
clientRequestId
serviceRequestIdFor our SharePoint failure, the result becomes:
The file or folder name contains characters that are not permitted. Please use a different name.Step 14 — Capture the Flow Name
For this demonstration, create:
Compose
Rename:
Compose_Flow_NameValue:
Employee Onboarding - Error Handling DemoFor a production framework, this can later be moved into configuration or an environment variable.

Step 15 — Capture the Run ID
Add:
Compose
Rename:
Compose_Run_IDExpression:
workflow()?['run']?['name']Example:
08584143084564250373668121992CU19The Run ID is useful because it allows the support team to identify the exact execution that failed.
Step 16 — Capture the Timestamp
Add:
Compose
Rename:
Compose_Error_TimestampExpression:
convertTimeZone(
utcNow(),
'UTC',
'India Standard Time',
'dd-MMM-yyyy HH:mm:ss'
)Example:
21-Aug-2026 13:17:10Step 17 — Capture the Status Code
Add:
Compose
Rename:
Compose_Status_CodeExpression:
first(body('Filter_Failed_Actions'))?['outputs']?['statusCode']For our SharePoint error:
400Step 18 — Create the Flow URL
Add a Compose:
Compose_Flow_URLFor this demonstration, use your flow's URL:
https://make.powerautomate.com/environments/default-53c989d3-ab06-4edc-8157-06d8640eea7f/flows/d7c723d7-ba25-4f8a-a931-00423bda820e/detailsIn a production solution, avoid hardcoding environment-specific URLs and use configuration/environment variables where appropriate.
Step 19 — Configure the Environment
Create a string variable:
EnvironmentNameValue:
ProductionRename the action:
Initialize_EnvironmentIn a proper Solution-based implementation, this should eventually be replaced with an Environment Variable.

Step 20 — Create the Error Object
Add a Compose:
Compose_Error_ObjectUse:
{
"FlowName": "@{outputs('Compose_Flow_Name')}",
"RunId": "@{outputs('Compose_Run_ID')}",
"FlowUrl": "@{outputs('Compose_Flow_URL')}",
"FailedAction": "@{outputs('Compose_Failed_Action')}",
"StatusCode": "@{outputs('Compose_Status_Code')}",
"ErrorMessage": "@{outputs('Compose_Error_Message')}",
"Timestamp": "@{outputs('Compose_Error_Timestamp')}",
"Environment": "@{variables('EnvironmentName')}"
}The final object contains all the information required for troubleshooting.

Step 21 — Create the HTML Error Email
Add:
Data Operation → Compose
Rename:
Compose_HTML_Error_EmailUse the HTML notification we created earlier.
The important part for the clickable Flow URL is:
<a href="@{outputs('Compose_Flow_URL')}"
target="_blank"
style="display:inline-block;background:#0078d4;color:#ffffff;text-decoration:none;padding:12px 26px;border-radius:5px;font-size:14px;font-weight:600;">
Open Flow
</a>The recipient will see an Open Flow button rather than a long URL.
Step 22 — Send the Error Notification
Add:
Office 365 Outlook → Send an email (V2)
Rename:
Send_Error_NotificationConfigure:
To:
Your support/admin emailSubject:
[Power Automate Failure] @{outputs('Compose_Flow_Name')}Body:
Outputs of Compose_HTML_Error_Email
Step 23 — Test the Complete Error Framework
Now intentionally create the failure again.
For example:
Employees/Error Test User:InvalidThe flow should execute:
TRG_New_Employee
✅
↓
TRY_Process_Employee
│
├── Get_Employee_Details ✅
│
├── Create_Onboarding_Folder ❌
│
└── Send_Welcome_Email ⏭️
↓
CATCH_Error_Handler
✅
↓
Filter_Failed_Actions
✅
↓
Compose_Failed_Action
✅
↓
Compose_Error_Message
✅
↓
Compose_Error_Object
✅
↓
Compose_HTML_Error_Email
✅
↓
Send_Error_Notification
✅
Step 24 — Final Email
The support team should receive an email similar to:
🔴 Power Automate Flow Failure
Flow Information
Flow Name
Employee Onboarding - Error Handling Demo
Environment
Production
Failed Action
Create_Onboarding_Folder
Status Code
400
Run ID
08584143084564250373668121992CU19
Failure Time
21-Aug-2026 13:17:10
Error Details
The file or folder name contains characters
that are not permitted. Please use a different name.
[ Open Flow ]The Open Flow button should open the Power Automate flow directly.

Final Architecture
At the end, your framework looks like:
TRG_New_Employee
│
▼
Initialize_Environment
│
▼
┌─────────────────────────────────┐
│ TRY_Process_Employee │
│ │
│ Get_Employee_Details │
│ Create_Onboarding_Folder │
│ Send_Welcome_Email │
└───────────────┬─────────────────┘
│
Failed / Timeout
│
▼
┌─────────────────────────────────┐
│ CATCH_Error_Handler │
│ │
│ Filter_Failed_Actions │
│ Compose_Failed_Action │
│ Compose_Error_Message │
│ Compose_Flow_Name │
│ Compose_Run_ID │
│ Compose_Error_Timestamp │
│ Compose_Status_Code │
│ Compose_Flow_URL │
│ Compose_Error_Object │
│ Compose_HTML_Error_Email │
│ Send_Error_Notification │
└─────────────────────────────────┘Conclusion
A production Power Automate flow should not simply tell the support team that "the flow failed."
A useful error-handling framework should provide enough information to answer:
Which flow failed?
Which run failed?
Which action failed?
What was the error?
What was the status code?
When did it fail?
Which environment was affected?
Where can I open the flow?
By using Scopes, Configure Run After, result(), expressions, structured error objects, and HTML email notifications, we can create a reusable error-handling pattern that can be applied to multiple production flows.

Join the conversation! Your thoughts help the community grow.