WorkflowRule returns zero rows in the Tooling API
Your migration checklist says "disable workflow rules." Your query returns nothing. Before you conclude the org is clean, work out which of three very different things just happened — because two of them mean automation is still armed.
Do not read zero as "clean"
This is the whole point of the page. A count of zero can mean any of the following, and they demand opposite responses:
| What happened | What you should do |
|---|---|
| The org really has no workflow rules | Nothing. Move on to flows. |
| The query ran but excluded them | Fix the query and re-check. |
| The query failed and something swallowed the error | Stop. Read the actual API response. |
A tool that renders all three as "0" is actively dangerous during a migration, because it tells you automation is off when it may be running. If you are writing one, keep the empty case and the error case separate all the way to the UI.
Cause 1: the org migrated, and this is now normal
Salesforce ended support for Workflow Rules and Process Builder on 31 December 2025, with a long-signalled push toward Flow. Existing rules generally keep running, but no new investment is going into them and Salesforce's guidance is to migrate.
The practical consequence for anyone writing migration tooling in 2026: an empty workflow rule result is increasingly the correct answer. Plenty of orgs finished their migration and have genuinely none left. If your checklist still treats "zero workflow rules" as suspicious, the checklist is out of date.
Confirm it the boring way — Setup → Process Automation → Workflow Rules. If Setup shows an empty list too, the org is clean and your query was right.
If workflow rules are gone, the automation you actually need to disable before a data load is flows and triggers. Confirm what replaced them rather than assuming the org simply lost its automation.
Cause 2: the query, not the org
A plain query is the right diagnostic. Add no filters at all first:
Then narrow. Two filter mistakes account for most false empties:
- Filtering on
Active = truewhile the rules exist but are already inactive. That is a legitimate zero for "active rules" and a misleading zero for "rules exist." - Filtering
TableEnumOrIdby object label rather than API name. It holds the API name for custom objects and an enum for standard ones, so a label-based filter silently matches nothing.
Run the unfiltered version once. If it returns rows, your filter was the problem and you now know exactly which one.
Cause 3: the call failed and you never saw it
This is the one that bites, and it is usually your own code's fault rather than Salesforce's. If the object isn't queryable in that org's configuration, or the composite request was malformed, Salesforce returns a non-200 with a real message — INVALID_TYPE, a malformed query, or an insufficient-access error. Any of these is informative. But a client that wraps the call in a broad try/catch and falls back to an empty array converts a useful error into a confident, wrong zero.
Then render the two states differently: "0 workflow rules" versus "couldn't read workflow rules — reason." The second is honest and lets the user decide.
If you log or display API errors, don't truncate them to a short preview. Salesforce puts the actionable part — the field or object it objected to — at the end of the message. Cutting the string at 160 characters throws away the only useful part, and you end up guessing at a problem the API already explained.
Why Industries and Vlocity orgs surface this most
Anecdotally this is where the empty-or-erroring result shows up most often. Those orgs carry very large managed packages, a distinct feature mix, and frequently a different automation history from a standard CRM org.
The engineering conclusion is not to special-case the org type. Detecting "is this a Vlocity org" is fragile and will drift. Handle the three outcomes — rows, empty, error — distinctly on every org, and Industries orgs stop being a special case at all.
Frequently asked
Can I deactivate a workflow rule through the Tooling API?
Where the object is writable in your org, yes — a PATCH on the record with the full Metadata passed back through. As with validation rules, GET the complete Metadata first and modify it, rather than sending a partial object.
Why does a partial Metadata update silently do nothing?
The Tooling API treats Metadata as a whole-object write. Send a subset and you can get a 204 with no effective change. Always GET, mutate the returned object, PATCH it back.
Should I migrate workflow rules to Flow before a data migration?
Not as part of the same change window. Two large changes at once makes failure impossible to attribute. Do the data migration with what exists, then migrate the automation separately.
Does Setup show packaged workflow rules?
Yes, and packaged ones can't be deactivated in the subscriber org — same package boundary as packaged Apex triggers.
What is the fastest way to inventory all automation in an unfamiliar org?
Query each type separately, keep the counts per type, and record whether each query succeeded, returned empty, or failed. That three-state inventory is the artefact you actually want before touching anything.
Where OrgKit fits
SF Automation Switch inventories validation rules, flows, processes, triggers, and workflow rules in one pass, and reports "unavailable" separately from "none found" — precisely because reading zero as clean is how migrations go wrong. It snapshots the state before you change anything so the revert is exact.
Free, runs in the browser, nothing stored server-side.
Open SF Automation Switch