You hit Delete on a field you're certain nobody uses, and Salesforce stops you with an error naming some dependency you'd forgotten about. So you go clear that one, try again, and it names another. The platform is protecting you from breaking something downstream, which is the right instinct — but it's drip-feeding you one blocker at a time, and what you actually want is the full list before you start.
The good news is that "the field is referenced somewhere" is a metadata question, and metadata is knowable. The catch is that no single native tool shows you every reference, so finding them all means layering a few methods and knowing where each one goes blind. Before any of that, get clear on which references actually matter.
What blocks deletion, and what just gets cleaned up
Not every reference is a wall. Salesforce blocks deletion when the field is baked into logic — a formula on another field, a roll-up summary, a validation rule, a flow, or an Apex class. Those are the references you have to clear before the field will go.
References on page layouts are cosmetic: delete the field and it simply drops off the layout, no error. References in reports and list views usually won't block deletion either, but they will quietly break or change those reports once the field is gone, which is its own kind of problem if you don't know they exist. So your real job is two-sided — clear the logic references that block you, and find the report and layout references that won't block you but will surprise someone next week.
One reassurance before you start: deleting a custom field isn't instant and irreversible. It sits in the object's deleted-fields list for 15 days, and you can restore it, with its data, during that window. After 15 days it's permanently erased. That undo buffer is worth remembering, because it means a careful delete is recoverable if you missed something.
Clear the logic that blocks the delete — and find the reports and layouts that won't block it, but will break quietly next week.
Method 1: the "Where is this used?" button
On a custom field's detail page, Where is this used? is the right first stop. Click it and Salesforce lists the metadata that references the field — formulas, validation rules, flows, layouts, Apex, and more. For a quick check on a single custom field, it's often enough.
Know its edges, though, because they're the reason it isn't the whole answer. It only works on custom fields — for a standard field like Opportunity.StageName, the button isn't there at all, and standard fields are exactly the ones with the most tangled dependencies. It tells you the name of the referencing component but not where inside it: "used in these five flows," without saying which element of which flow, so you still open each one and hunt. And it has documented holes — references to reports across certain foreign-key relationships don't appear, only reports the running user can see are returned, joined reports aren't covered, and the list caps at 2,000 entries. Treat it as a fast first pass, not a clearance.
Method 2: the Dependency API
When you want something queryable that also covers standard fields, the Tooling API's MetadataComponentDependency is the next layer. You query for everything that references your field by its component id:
SELECT MetadataComponentName, MetadataComponentType
FROM MetadataComponentDependency
WHERE RefMetadataComponentId = '00NXXXXXXXXXXXXXXX'
That returns the components depending on the field and what type each is, for standard and custom fields alike — a real step up from the button. You can run it from the Developer Console, the CLI against the Tooling API, or a quick script.
The honesty here matters, because this one looks more authoritative than it is. MetadataComponentDependency has been in Beta for years; Salesforce explicitly says it isn't covered under your main agreement and can be discontinued, so don't build a permanent process on it without that in mind. It carries the same 2,000-result cap as the button and allows only limited filtering. It counts inactive flows as references, so you'll see dependencies that can't actually fire and have to reason about which ones are live. And it doesn't capture everything — managed-package internals and some metadata types are incomplete, and Apex coverage in particular has known gaps. Some orgs also need Salesforce to switch the API on before it returns anything. It's genuinely useful and genuinely partial at the same time.
Method 3: retrieve the metadata and search it
When you need to be thorough — especially on a standard field, or before deleting something load-bearing — nothing beats pulling the metadata and searching it as text. Retrieve the relevant metadata with the Salesforce CLI and grep for the field's API name across every file:
sf project retrieve start --metadata CustomObject Flow ApexClass ValidationRule
grep -rln "Region__c" force-app/
Because the field's API name appears literally in the XML of any flow, validation rule, formula, or Apex class that references it, this catches references the button skips and works on standard fields the same as custom ones. It's the most complete static method you have on your own.
Its blind spot is the one every static method shares, and it's worth saying plainly: a reference assembled dynamically — a field name built from a string in Apex, or composed at runtime — won't appear in the metadata as a literal, so no text search and no dependency tool, native or third-party, will catch it. That's why the last step before deleting anything significant is a deploy to a full sandbox and a real test, not a tool's all-clear. The tools narrow the risk; the sandbox confirms it.
The shortcut, and the limit it doesn't remove
This is the trace SchemaForce resolves in one place. Point it at a field — standard or custom — and it surfaces every metadata reference across the org in a single view, past the 2,000-row cap, without the per-field button-clicking, the Beta fragility, or the standard-field gap that send you bouncing between the three methods above. Because a reference is metadata, it reads only schema and configuration to do this, never the contents of a record, so you can run it against production while you're deciding what's safe to retire. It pairs naturally with field-usage data: usage tells you whether a field is worth keeping, references tell you what you have to clear before you can remove it.
The limit it shares with everything else is the honest one to close on. Static reference analysis, however complete, cannot see a reference that only exists at runtime. SchemaForce will give you a far fuller picture than any single native tool, faster, but it will not replace the final sandbox test on a field that's deeply embedded — and a tool that told you otherwise would be lying to you. Use it to go from "I have no idea what touches this" to "here's the complete static picture," then let the sandbox close the last gap.
Order of operations
- Decide what you're clearing. Logic references — formulas, validation rules, flows, Apex, roll-up summaries — block deletion. Layout references auto-clean; report references break quietly. Find both kinds.
- Fast pass with
Where is this used?on custom fields, remembering it skips standard fields, the where-within detail, and some reports. - Go queryable with the Dependency API when you need standard-field coverage — but treat its results as partial, watch for inactive flows, and mind the 2,000 cap and Beta status.
- Search the retrieved metadata when it has to be thorough; the API name appears literally everywhere it's statically referenced.
- Test the delete in a sandbox before production. Static analysis can't see dynamic references, and the 15-day restore window is your backstop, not your plan.
Work it in that order and "why won't this field delete" stops being a guessing game and turns into a checklist you can actually finish.



