What it does
A house standard for what "production-ready" means in a flow, so that reliability is a checklist rather than a matter of who built it. Five things carry the weight: scoped try/catch, deliberate retry policy, alerting that reaches a human, idempotency on writes, and a defined fallback when the automation can't finish.
Key facts
- Run After settings control what happens when an action fails, times out, is skipped or succeeds. Scopes plus Run After give you the try/catch/finally shape; there's no dedicated construct.
- The
workflow()function returns the run's identifiers, environment name and flow display name, which is what makes a logged failure traceable back to a specific run URL. result()against a scope name returns status, inputs, outputs and error for every action inside it, so a catch scope can name the exact action that failed.- Retry policies apply per action and default to exponential interval. Exponential is preferred over fixed because it spreads attempts out instead of hammering a service that's already struggling.
- Every retry consumes a Power Platform request. A retrying action against a throttled or dead endpoint burns allocation while achieving nothing.
- Terminate stops a run and sets its status. A failure that's caught and handled without Terminate reports the run as Succeeded — which matters if anything downstream counts failed runs.
- The platform emails flow owners about common critical failures such as broken connections and throttling, and a flow whose trigger or actions fail continuously is switched off after 14 days.
- Application Insights can be wired to cloud flows for alerting, which is the right answer once custom logging starts adding meaningful action cost.
When to use / skip
Apply the full standard to anything that writes to a system of record, anything with a business owner, and anything running unattended. That's most of what you'll be paid to build. Personal productivity flows and genuinely self-correcting automations — where the next trigger fixes whatever the last run got wrong — can skip it, and pretending otherwise just makes people ignore the standard entirely.
The part teams get wrong isn't the try/catch, which everyone eventually copies from somewhere. It's idempotency and it's ownership. A flow that creates a record and then fails will, on retry, create a second record. A flow that logs its failure to a Dataverse table nobody has ever opened has not been alerted on. Decide both before build, because retrofitting idempotency into a live integration is genuinely unpleasant work.
Configuration decisions
- Which actions are idempotent. Non-idempotent writes — payments, record creation, outbound email — should have retry set to none so failure is visible rather than duplicated.
- Whether a failure stops the run or is caught and compensated. Both are valid; the wrong one is deciding by accident.
- Where alerts land and who owns that queue. Teams channel, ticketing system, on-call rota — pick one with a human attached and get the client to name them.
- Whether the flow reports a caught failure as Succeeded or Failed. If monitoring counts failed runs, catching everything makes your problems invisible.
- What the human fallback is when the automation genuinely can't complete. Queue the item for manual handling, raise a task, or notify the requester — but decide, don't leave it silent.
- Action timeouts on long-running calls, so a default retry ladder doesn't occupy the run for an hour before giving up.
Gotchas
- A finally scope needs all four Run After conditions ticked. Tick only "is successful" and "has failed" and it's skipped whenever the try scope was itself skipped.
- Catch scopes only catch what's inside the try scope. Failures before it, and a Terminate inside it, are not caught.
- Retries are invisible in the run history summary. A run that took 55 minutes was probably retrying a dead endpoint, and every attempt was billed.
- Custom logging is an anti-pattern past a certain volume. Microsoft says so plainly — excessive logging actions degrade performance and cost real allowance. Push heavy telemetry to Application Insights instead.
- Secure outputs hides error payloads from run history as well as from prying eyes. That's sometimes correct and always makes support harder, so make it a deliberate decision.
- Duplicate approval requests and duplicate records are almost always default retries on a non-idempotent action. The run history shows one action, which is why it takes people so long to find.
Consultant notes
- Build one reusable error-handler child flow at the start of the engagement — takes flow name, run URL and error detail, writes a log row, notifies the owner. Then every flow gets the house standard for the cost of a single action.
- Make error handling an acceptance criterion, not a best practice. Best practices get dropped when the sprint gets tight; acceptance criteria don't.
- Get the client to name a failure owner before go-live. The pattern is easy and the operational ownership is what actually gets missed.
- Warn about the 14-day auto-disable rule, especially around system decommissions. A consistently failing flow gets switched off, not just noisy.
- On an inherited estate, audit retry policies on write actions first. It's the highest-yield review you can do in an afternoon.
Reread before signing off any flow that touches money, contracts or a system of record