When a Salesforce Flow breaks at 2 a.m., nobody knows which Flow did it. The data field shows the wrong value, the record sits untouched, and the only signal is a vague "An error occurred" inside the user's Flow Run History. The audit trail is incomplete. The deferred work is invisible. Nobody thought to add a fault path.

This guide is the admin's end-to-end Flow health audit. It covers how to inventory every Flow in an org, what a fault path is and why missing ones are the single most common silent-failure mode, what 100% Flow coverage actually looks like, the Setup and Workbench checks you can run from a browser today, and when it's time to escalate to a Founding Audit.

40–60% of Salesforce orgs have Flow inventory gaps or fault-path holes. That's not a guess — it's what org audits consistently surface. Each missing fault path is a Flow that fails silently and a record that sits untouched.

1. How to Inventory Flows Across an Org

The first problem with Flow audits is that most admins don't know how many Flows they have, much less which ones are doing what. Salesforce Setup hides the truth in plain sight: the Setup → Flows list shows every Flow one screen at a time, paginated, with no export, and no way to bulk-open the metadata.

To get a real inventory — every Flow, every version, every status — you need to talk to the metadata API directly. Three approaches, ordered from lightest to heaviest:

Option A: SOQL via Workbench or Developer Console

The Flow object is queryable. Run this query from Workbench (or the Developer Console's Query Editor) to enumerate every Flow in the org:

SELECT Id, MasterLabel, ProcessType, Status, VersionNumber, LastModifiedDate, CreatedDate
FROM Flow
WHERE Status = 'Active'
ORDER BY MasterLabel ASC

What you get back is the truth. Each row tells you a Flow's MasterLabel (the human-readable name shown in Setup), the ProcessType (Record-Triggered Flow, Schedule-Triggered Flow, Screen Flow, Platform Event, Auto-Launched Flow), the Status (Active, Draft, Obsolete), and the VersionNumber.

The "Obsolete" status trap

A Flow in Status = 'Obsolete' is one that has a newer Active version. Out-of-the-box, Salesforce keeps obsolete versions around for in-flight transaction integrity. But many Flow audit tools count all versions toward "Flow count" — inflating the total. If your audit says you have 240 Flows but you only actually run 130, obsolete versions are the usual culprit.

When counting Flows for an audit, filter to Status = 'Active' only. The obsolete rows are a hygiene trail, not an active surface.

Option B: Salesforce CLI retrieval

If you've installed the Salesforce CLI (sf) and authenticated to the org, you can pull every Flow's underlying metadata as XML files in one shot:

sf project retrieve start -m Flow:*

This writes every Active Flow to a local flows/ folder as .flow-meta.xml. Once you have the XML, you can grep for fault connectors, entry criteria, and references to deleted fields — the three most common architectural problems.

Option C: Programmatic metadata API access

For orgs with hundreds of Flows, the right move is a programmatic retrieval — write a small script that calls the Metadata API's listMetadata and retrieveZip calls, unpack the zip, and parse each .flow-meta.xml file to score it for fault coverage, inactive versions, recursion risk, and broken field references. That is what the Flow Health Auditor does — it reads your org's Flow metadata, scores each Flow, and surfaces the highest-risk ones first in minutes.

Whichever method you use, the deliverable is the same: a list of every Active Flow, with its ProcessType, its entry criteria summary, and a flag for whether it has DML actions that should have fault paths.

2. What a Fault Path Is and Why Missing Ones Matter

Every action element in Flow — Create Records, Update Records, Get Records, Send Email, Apex Actions — has a fault output. When the action fails (DML error, permission error, validation rule, governor limit), the fault path fires. If you don't connect it, the error goes unhandled and the Flow either stops silently or throws an opaque error to the user.

The cost of a missing fault path isn't theoretical — it's the reason your dashboards have stale records and your users have learned not to trust automation. A Flow that updates an Opportunity's Stage and fails silently because of a missing fault path leaves the Stage at the wrong value with no error surfaced, no retry, and no notification.

The silent-failure scenario

A record-triggered Flow auto-creates a Task on every closed-won Opportunity. The Task creation fails because the assignment rule throws a validation error. Without a fault path, the Opportunity sits at "Closed Won" with no Task created. The rep assumes the task was created. A week later, the customer hasn't been onboarded. The first signal of the failure is the customer complaint.

With a fault path, the same Flow would route the failure to an Error Log object and notify the admin — the missed Task would be visible before it became a customer problem.

Fault paths aren't optional architecture. They are the contract between a Flow and the rest of your org: a guarantee that failures will be visible, logged, and routable. The deeper patterns (shared error subflows, scheduled-Flow recovery, validation-rule message extraction) live in the companion guide referenced above. For audit purposes, the only question is: does every action element have a connected fault path?

3. What 100% Flow Coverage Looks Like

"Flow coverage" doesn't mean "every record-trigger has a Flow" — it means every Flow that could fail has a defined failure path, every scheduled Flow has a guard to prevent re-running on already-processed records, every Screen Flow has a transactional rollback pattern, and every Get Records element handles the empty result case.

Here are the components of 100% Flow coverage, and what each looks like when it's correctly in place:

Coverage Component What It Means What "Good" Looks Like
Entry criteria The conditions that cause a record-triggered Flow to fire Narrow, specific, indexed-aware (no "any record change" triggers on objects with heavy write volume)
Decision branches Every Decision element covers every possible path Default outcome explicitly handled, no Flow paths that assume one of the branches will always be true
Action fault paths Every action element (Create, Update, Delete, Get, Send, Apex) has a fault connector routed to handling Shared Error Subflow with logging, retry, and escalation; no unhandled fault outputs
Scheduled Flow guard A scheduled Flow has a guard condition to prevent re-processing on already-completed records Processed__c checkbox and Retry_Count__c field in the entry condition; idempotent across runs
Screen Flow rollback A Screen Flow that performs DML has a pattern to handle failures without orphaning partial state Stage changes in Flow variables until a final "Confirm" step performs all DML in one commit; rollback is invisible to the user
Get Records empty state Every Get Records element followed by a Decision that checks result count before proceeding Explicit "no records" path on every Get; no silent skips where an empty filter would let an Update try to write to "nothing"

An org with 100% coverage has Flows that fail loudly. An org with partial coverage has Flows that fail loudly on the covered paths and silently on the uncovered paths — which is the worst possible state, because admins can't even tell which Flows are reliable.

4. Simple Health Checks You Can Run From Setup or Workbench

You don't need a paid audit tool to find the highest-impact Flow health problems. Five checks, each one runnable from a browser in under an hour:

Check 1: Fault path presence via Flow XML <faultConnector>

How to find it: Retrieve every Flow metadata file with sf project retrieve start -m Flow:*, then grep each Flow for the string faultConnector. Count the action elements (Create, Update, Delete, Send, Apex, Get with "Fault if No Elements") and compare to the number of fault connectors. Any action element without a fault connector is a silent-failure risk.

What good looks like: Every action element has at least one <faultConnector> node in the XML, and each fault connector routes to a handling element (a Decision that branches on the error, a Subflow that logs the error, a Screen that surfaces the message to the user).

Check 2: Scheduled Flow entry-condition guard

How to find it: Filter Setup → Flows by ProcessType = Schedule-Triggered Flow and Status = Active. Open each. Inspect the Start element's entry condition. Look for a Processed__c checkbox, a Retry_Count__c field, or any other "have I run against this record before?" guard.

What good looks like: A entry condition that filters out records already marked as Processed__c = true AND has a retry counter to prevent infinite looping on the same failure. The Flow is idempotent — running it twice on the same input produces the same result.

Check 3: Get Records "No Elements" handling

How to find it: Grep every retrieved Flow XML for GetRecords elements. For each one, check whether it's immediately followed by a Decision that branches on the size of the result collection. The pattern: {!Get_Records_Variable.Size} > 0.

What good looks like: Every Get Records is followed by a Decision. The "true" branch processes the records; the "false" branch handles the empty case explicitly (with an alert, a create-new-record path, or a graceful skip — never a silent skip).

Check 4: Inactive version count

How to find it: Run the Workbench SOQL query again, but group by MasterLabel:

SELECT MasterLabel, COUNT(Id) totalVersions,
       SUM(CASE WHEN Status = 'Active' THEN 1 ELSE 0 END) activeVersions,
       SUM(CASE WHEN Status = 'Obsolete' THEN 1 ELSE 0 END) obsoleteVersions,
       SUM(CASE WHEN Status = 'Draft' THEN 1 ELSE 0 END) draftVersions
FROM Flow
GROUP BY MasterLabel
ORDER BY COUNT(Id) DESC

Flows with 5+ obsolete versions are usually candidates for cleanup — the inactive versions hold no business logic value once the new version has been in production for a quarter.

What good looks like: Each Flow has exactly 1 Active version and 0 Draft versions. Obsolete versions may exist for transaction integrity but their count shouldn't keep growing indefinitely.

Check 5: Flows referencing deleted fields

How to find it: Grep every Flow XML for the field API names referenced in Get/Update/Criteria elements, then cross-reference each name against the current metadata catalog. Any field that no longer exists is a broken reference — the Flow either fails silently or surfaces a vague runtime error.

# After 'sf project retrieve start -m Flow:*'
grep -rho '<field>[A-Za-z0-9_]*__c</field>' flows/ | sort -u

What good looks like: Every field referenced in any Flow still exists in the org's metadata. If you find references to fields that have been deleted, audit whether the Flow still needs them — usually the reference is dead and the criteria should be updated or the Flow retired.

Run the Full Flow Health Scorecard in Minutes

The Flow Health Auditor retrieves every Flow's metadata, scores fault coverage, flags missing fault connectors, surfaces broken field references, and ranks the highest-risk Flows first. No Salesforce credentials required for the CSV-based scan.

5. From Manual Audit to Founding Audit

The five checks above catch the highest-impact problems — missing fault paths, broken field references, scheduled Flow idempotency holes, stale obsolete versions, and silent Get Records failures. For an org with fewer than 50 Flows, you can complete the whole audit in a half-day.

For orgs with hundreds of Flows, the bottleneck is no longer detection — it's prioritization. Which of the 30 Flows missing fault paths do you fix first? Which broken field references are actively breaking record updates, and which are dead code paths that haven't fired in months? Which scheduled Flows are running silently because nobody's looking at the log?

A Founding Audit runs the full scoring, prioritizes the findings by active blast radius (which Flows are firing today and how often), and surfaces the fixes in the order they'll have the highest reliability return. It's the same step you'd run manually — automated, repeatable, and tied to findings the team can action in one sprint.

Frequently Asked Questions

How often should I run a Flow health audit?
Every quarter for actively-maintained orgs, every six months for stable orgs. Run it immediately after any major org change — a release that adds 5+ Flows, a sandbox promotion that includes active Flow diffs, or a consulting engagement that touched the Flow library.

What's the difference between a "Flow health audit" and a "Flow scorecard"?
An audit enumerates problems: every Flow missing a fault path, every Flow referencing a deleted field, every Flow with 5+ obsolete versions. A scorecard weights those findings by impact and surfaces the top-N Flows to fix first. Most teams start with an audit to understand their full surface, then convert to a scorecard for prioritization on the second pass.

Does Process Builder still show up in a Flow audit?
Yes — until Salesforce retires it on December 31, 2026. Process Builder processes appear as ProcessType = Workflow in the Flow SOQL query and should be migrated to Flows before the retirement deadline. Each Process Builder process is a silent-failure risk for the same reason old Flows are: unhandled errors, no fault paths, and no clean migration path once the underlying process is retired.

Can I run a Flow health audit without a Salesforce administrator login?
Yes. The CSV-based Flow Health Auditor scans an exported Flow metadata export (which any admin with read-only org access can produce). For org-scale audits, a connected-org scan is faster — but the CSV path works for consultancies that can't be granted full org access.

What's the most common Flow issue you find?
Missing fault paths. Roughly half of the Findings the auditor raises fall into that one category. The fix is mechanical — connect a fault path to a shared Error Subflow — but the rollout is organizational: every dev who writes a Flow has to remember to do it. Fault path awareness in code review is the single highest-impact process change you can make.

Continue Reading