Auditing unused fields
A list of fields nothing references is easy to produce and easy to misuse. Here is what the list means, what it cannot see, and how to work through it without breaking something.
What the list is
A Salesforce field with no resolved inbound reference in the graph: no formula reads it, no layout places it, nothing filters or queries on it. In the app it is the Unused page; from the CLI it is meshie unused.
Each finding carries a risk note explaining what the absence does and does not prove. The --json form carries that note and the evidence; the human listing prints the ids. Read the note.
meshie unused --json | jq -r '.[] | "\(.node_id)\t\(.risk_note)"'What it cannot see
- Record data. Meshie reads metadata, never records. A field nothing references in configuration may still hold values someone exports to a spreadsheet every quarter.
- Dynamic code. Apex that assembles a field name at runtime produces an unknown edge rather than a resolved one, and unknown edges do not count towards in-degree. See below.
- Systems you have not connected. The graph is as wide as your integrations. An unused verdict from a Salesforce-only workspace means unused in Salesforce.
- API traffic from outside. An external tool reading the field over the REST API leaves no trace in metadata unless it shows up as a connected system.
A workable order
- Connect everything first. Auditing before your warehouse and automation tools are connected produces a longer list and a worse one.
- Sort by what you recognise. Fields with names like
Legacy_,Old_,Temp_or a year in them are where the real wins are, and where you have the institutional memory to judge. - Check each candidate in Impact. Unused says nothing points here; Impact shows you the same conclusion with the reasoning, and tells you when it cannot confirm it.
- Deprecate before deleting. Remove it from layouts, mark it as deprecated in its description, and leave it for a cycle. If something was reading it invisibly, you find out while the field still exists.
- Re-scan after the change so the graph reflects what you did and the next audit does not re-propose it.
The case the list does not separate out
Unused is in-degree zero over four kinds of resolved reference: REFERENCES_IN_FORMULA, LAYOUT_PLACEMENT, FILTERS_ON and SOQL_QUERY. Permission grants are excluded deliberately, since nearly every field in a real org has one regardless of use, and counting them would empty the list. Managed-package fields are excluded too: they can look unused by the same measure, and you cannot delete them anyway.
Unresolvable references are not in that set either. So a field that something reaches through dynamic Apex can appear on this list, and today it appears alongside the rest rather than flagged. The risk note on every finding says as much in words, and Impact is the surface that reads the flag and answers “can’t confirm this is unused”. That is why step 3 above is check each candidate in Impact, not a formality.