How to Handle a Failed Flow Call in Power Apps
When a flow call fails, Power Apps shows a red banner with the raw error, which means little to the people using the app. Wrap the call in IfError so a failure becomes a blank result, then say what happened in your own words: a Notify banner for the moment, and a label that stays on the screen.
Microsoft's error handling article shows the principle: when IfError replaces an error with a value, the error is replaced with a valid value and the error banner goes away.
The example is the Waiting for Approval screen of the Overtime Timesheet app. Its Refresh button runs a flow that returns the entries waiting for an approver.
Prerequisites
- A flow call in a button's OnSelect (How to Run a Flow and Use Its Result in Power Apps).
- The basics of
IfError(How to Handle Errors in Power Apps with IfError).
Step 1: Wrap the Call Itself in IfError
Put IfError directly around Run(), with Blank() as the replacement, and keep the result in With:
With(
{ response: IfError(GetWaitingApprovals.Run(), Blank()) },
...
)
Not around the UpdateContext that stores the result: UpdateContext stores an error without failing, so an IfError around it never sees one. That's the mistake I made first (Fixed: IfError Doesn't Catch a Flow's Run Failed Error in Power Apps).
Step 2: Branch on the Result
If response is blank, the call failed: set a failure flag and show a Notify message (How to Show a Notification in Power Apps with Notify). Otherwise, clear the flag and use the result:
UpdateContext({ locIsLoadingWA: true });
With(
{ response: IfError(GetWaitingApprovals.Run(), Blank()) },
If(
IsBlank(response),
UpdateContext({ locLoadFailedWA: true });
Notify("The entries waiting for you couldn't be loaded. Select Refresh to try again.", NotificationType.Error),
UpdateContext({
locLoadFailedWA: false,
locEntriesWA: ForAll(
ParseJSON(response.entries),
{
ID: Value(ThisRecord.id),
Employee: Text(ThisRecord.employee),
Department: Text(ThisRecord.department),
StartTime: DateTimeValue(ThisRecord.startTime),
EndTime: DateTimeValue(ThisRecord.endTime),
BreakMinutes: Value(ThisRecord.breakMinutes),
SavedOn: DateTimeValue(ThisRecord.savedOn)
}
)
})
)
);
UpdateContext({ locIsLoadingWA: false })
The message says what happened and what to do next, in plain words.
Step 3: Keep the Failure on the Screen
The Notify banner closes after a few seconds. A label shows the same sentence until the next try. One label serves both the failure and the empty list:
If(
locLoadFailedWA,
"The entries waiting for you couldn't be loaded. Select Refresh to try again.",
"Nothing is waiting for your decision. Select Refresh to check again."
)
!locIsLoadingWA && (locLoadFailedWA || IsEmpty(locEntriesWA))
The list and its summary hide while the flag is set:
!locIsLoadingWA && !locLoadFailedWA && !IsEmpty(locEntriesWA)
The Result
When the call failed, the app showed my message in the banner and on the screen, with no raw error:

After the banner closed, the label kept the message:

Finding Out What Went Wrong
The plain message hides the details from the person using the app, so look for them elsewhere. If the flow started, its run history shows the failed action (How to See a Flow's Run History in Power Automate). If no run appears, the call failed before the flow started, for example because the flow isn't shared with that person (Fixed: "Does Not Have ReadAccess Right(s) … of Entity Process" When Power Apps Runs a Flow).
Common Mistakes
| Mistake | What happens | Do this instead |
|---|---|---|
IfError around UpdateContext | The failure isn't caught; the raw banner shows | IfError around Run() |
Only a Notify | The screen gives no reason once the banner closes | A label as well |
Showing FirstError.Message to everyone | Raw errors, such as IDs and server addresses | A plain sentence |
| No way to try again | People reload the whole app | A Refresh button |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The raw Run failed banner still shows | IfError doesn't wrap Run() | Move it onto the call |
| The screen goes blank after a failure | Visible formulas use a variable that holds an error | Store a blank and a flag |
| The fix doesn't show in the published app | The browser still runs the old version | Open the app again a few minutes after publishing |
FAQ
Should the flow also handle its own errors?
Yes, where it can. A flow that responds with a clear result in every case is easier for the app to handle than one that fails. The app still needs IfError for calls that never reach the flow.
Can I log the error somewhere?
IfError's replacement can do more than return a blank, such as recording FirstError.Message with Trace. The error handling article covers FirstError and App.OnError.
Conclusion
Wrap Run() in IfError(..., Blank()), set a failure flag when the result is blank, and tell people what happened in a Notify banner and a label that stays. Keep the raw error for the run history.
