Fix Guides

How to Fix "An Unhandled Fault Has Occurred in This Flow"

Step-by-step fix guide with AI-powered diagnosis from BuildForce.

This generic message means a flow element failed and no fault path was connected to catch it — so the interview aborts and the running user sees this instead of the real error. It's almost always a Create/Update/Delete Records, Get Records, or Action element that hit a validation rule, a duplicate rule, a missing required field, a row lock, or an unhandled Apex exception. The fix is to wire fault paths on every data-touching element, capture the real message via $Flow.FaultMessage, and route failures somewhere your team will actually see them.

What Causes This Error

  • No fault path wired on a Create/Update/Delete Records or Get Records element — the most common cause by far.
  • A validation rule blocking the DML the flow is trying to perform, with nothing to catch it.
  • A duplicate rule set to "Block" stopping record creation.
  • A required field on the target object left unpopulated by the Create/Update Records element.
  • Row-lock contention (UNABLE_TO_LOCK_ROW) inside a record-triggered flow updating a busy parent record.
  • An Apex Action or invocable method throwing an unhandled exception back into the interview.
  • Flow interview limits (element count, recursion depth) being exceeded in an overly complex flow.

How to Fix It — Step by Step

  1. 1. Capture the real error first. Turn on flow error emails (on by default) or reproduce the failure while watching a Debug Log filtered to Flow. The generic on-screen message tells you nothing — $Flow.FaultMessage and the error email contain the actual exception (validation rule text, duplicate rule name, field name, or Apex stack trace).
  2. 2. Wire a fault path off every data-touching element. Drag from the element's connector dot and choose the fault (red X) path for every Create Records, Update Records, Delete Records, Get Records, Apex Action, and subflow call. Unconnected fault connectors are exactly what produces this generic message.
  3. 3. Build one reusable error-logging subflow. Create a subflow that takes $Flow.FaultMessage, $Flow.InterviewGuid, $Flow.CurrentDateTime, the flow's API name, and the relevant record Id as inputs, and writes them to a simple custom object (e.g. Flow_Error_Log__c). Call this subflow from every fault path instead of building one-off logging per flow.
  4. 4. Give screen flows a real error screen. Route the fault path to a friendly screen ('Something went wrong — we've logged it and a team member will follow up') instead of letting the interview terminate on Salesforce's default fault screen.
  5. 5. Give unattended flows an alert, not just a log row. Record-triggered and autolaunched flows have no user watching the screen, so a log record alone can sit unnoticed. Send an email alert or post to a monitored channel from the fault-handling subflow so failures get triaged.
  6. 6. Fix the cause the fault path reveals. A fault path that fires is a symptom, not the fix. If it's a validation rule or duplicate rule blocking the DML, address why the flow is producing data that trips the rule. If it's a missing required field, populate it in the Create/Update Records element. If it's UNABLE_TO_LOCK_ROW, see the row-locking fix guide.
  7. 7. Test the failure path on purpose. Leave a required field blank, or trigger the duplicate rule intentionally, and confirm your fault screen or log entry fires — not the generic Salesforce message. Most fault paths are never actually exercised until the first real production failure, which is too late to find out they're wired wrong.

Reading the Real Error

Add a text template or screen component bound to {!$Flow.FaultMessage} inside your fault path (or log it via the subflow above) — this is where the actual exception text lives, including the validation rule error message or the specific Apex stack trace, instead of the generic message the running user would otherwise see.

This Error Is a Symptom, Not the Root Cause

If one flow is missing fault paths, it's rarely the only one — most orgs build flows from a copied template, so a missing fault path pattern tends to repeat across dozens of automations. Run BuildForce's free health check to see how your org's overall setup compares to similar companies in your industry and size band, then connect your org so BuildForce can flag every flow missing a fault path, not just the one that already failed on a user.

How BuildForce Prevents This

FAQ

Why does Salesforce show "An unhandled fault has occurred in this flow" instead of the real error?

Because no Fault path was connected to the element that failed. When an element (Create Records, Update Records, Delete Records, Get Records, an Apex Action, or a subflow call) throws an error and there's no fault connector wired from it, the flow interview aborts and Salesforce falls back to this generic message for the running user. The real error — a validation rule, a duplicate rule, a missing required field, a row lock, or an Apex exception — is captured in $Flow.FaultMessage and in the flow's error email, but never shown on screen unless you build a path to display it.

Where do flow error emails go, and can I redirect them?

By default, Salesforce emails the user set as "Run As" for the flow (or the flow's last-modified admin for autolaunched/record-triggered flows). You can't redirect the built-in email, but you can stop relying on it: wire every fault path into a shared error-logging subflow that writes to a custom object (or fires a Platform Event) so failures show up in a queue your team actually monitors, instead of an inbox.

Do I need a fault path on every single element?

Every element that performs a DML operation, a query, or calls out to Apex can fail — Create/Update/Delete Records, Get Records, Apex Actions, and subflow calls are the usual suspects. Screen elements, Assignment, and Decision elements can't fail in the same way and don't need one. As a rule: if the element has a database or Apex boundary, give it a fault path.

Can a fault path itself fail?

Yes — if your fault-handling logic also does DML (e.g., creating a log record) and that DML fails too, the flow will still show the generic unhandled-fault screen. Keep fault-path logic minimal and defensive: log to a simple object with as few required fields and validation rules as possible, and give the "create log record" element inside the fault path its own fault path that falls back to nothing more than a generic screen.

Does BuildForce catch missing fault paths automatically?

BuildForce's flow health checks flag Create/Update/Delete/Get Records and Apex Action elements that have no fault path connected, before the flow reaches production — so you find out from a report instead of a user's support ticket.