A rep messages you: "I can't see the Discount field on this opportunity, but my teammate can." Or worse, the reverse — someone can see a field they have no business seeing, and now it's a compliance question. Either way, you open Setup, start clicking, and twenty minutes later you're four permission sets deep and no closer to an answer.
The reason this takes so long isn't that you're bad at it. It's that "can this user see this field" is not a setting you can look up. It's a resolved outcome — the sum of object access, field-level security, page layout, record visibility, and record type, all interacting. The native tools have gotten much better at answering one of those layers. The trouble is that the layer causing your specific ticket is usually a different one.
So before you open a single permission set, ask the question that tells you which layer you're actually in.
First move: is it the field, or is it the record?
This one question saves more time than any tool. When a user says they can't see a field, they almost never mean it literally. They mean a field is blank, or absent, on a record in front of them — and that has at least three unrelated causes.
Check two things. Can the user see other fields on that same record? And can they see this field on other records?
If they can't see the record's other fields either, you don't have a field problem. You have a sharing problem — they can't see the record, full stop, and field-level security is a red herring. If they can see this field fine on other records but not this one, you're looking at record-level access or a record-type-driven layout difference, not FieldPermissions. Only when the field is consistently missing for this user across records that they can otherwise see are you actually in field-level security.
Most wasted troubleshooting time comes from someone diving straight into FLS for what turns out to be a layout or a sharing issue. Sort that first.
Before you open a permission set, ask whether it's the field or the record. That one question tells you which layer you're actually in.
The layers, in the order they actually break
Field visibility resolves through a stack. Walk it in this order, because the cheap checks are also the most common culprits.
Object access comes first. If the user doesn't have Read on the object through any profile or permission set, nothing below this matters. This is rarely the cause for an established user, but it's a five-second check and it short-circuits everything else.
Field-level security is the layer everyone checks first and the one that's now well-tooled. FLS is additive and most-permissive: a user gets Read on a field if any assigned profile, permission set, or permission set group grants it. You don't need to find the one place it's turned on — you need to confirm none of them turn it on. The only thing that subtracts is a muting permission set inside a permission set group, which is worth remembering precisely because it's the one case that violates the "additive" mental model and will quietly confuse you.
Page layout and Dynamic Forms are where the false alarms live. A field can have FLS Read and still be absent from the record page simply because it isn't on the layout — or on the Dynamic Forms region — assigned to that user's profile and record type. This is the single most common "I can't see the field" that is not an access problem at all. The tell: the field is missing on the page but shows up fine in a report, a list view, or the API. If that's the case, stop looking at permissions. And if you're on Dynamic Forms, check the component visibility filters too, because a field can be conditionally hidden based on criteria that have nothing to do with who the user is.
Record type and picklist values explain the subtler version — the user sees the field but not a particular value. Picklist value availability is set per record type, so "I can't pick Tier 1" is a record-type question, not an FLS one.
Sharing is the layer to return to if your first move pointed at the record rather than the field. Org-wide defaults, role hierarchy, sharing rules, and manual shares decide which records a user sees; none of them touch field visibility directly, but they produce the same symptom and send people down the wrong path constantly.
What the native tools now do well — and where they stop
Give Salesforce credit: the FLS layer used to mean clicking through every permission set by hand, and it doesn't anymore.
On a user's detail page, View Summary opens the User Access Summary, which shows that user's object, field, and custom permissions in one place, and the Access Granted By action tells you which profile or permission set is granting a given permission. That answers "what does this user have and where did it come from" for the permission layers without the manual hunt.
Newer still, Summer '26 added a Field Access view inside Object Manager. Pick an object, pick the field, and you get a read-only summary of field-level security across profiles, permission sets, and permission set groups in a single screen. It's the fastest native answer yet to "who can access this field."
Here's the honest boundary. Both tools resolve the permission layers — object and field security — and they resolve them well. Neither one knows that the field is simply missing from a page layout. Neither one accounts for a Dynamic Forms visibility filter, a record-type difference, or whether the user can see the record in the first place. They answer one user at a time or one field at a time, in the UI, for the org as it exists this minute. So they shorten the FLS step, which is real progress, but they don't hand you the cross-layer diagnosis your ticket actually needs, and they don't help when the question is "show me this across every field and every user" or "what changed since last week."
If you'd rather not click at all, the FLS layer is queryable. The user's permission containers — their profile and every assigned permission set and group — come from PermissionSetAssignment, and the field grants come from FieldPermissions, where each Parent is a permission set and profiles appear as permission sets with IsOwnedByProfile = true:
SELECT Parent.Label, Parent.Profile.Name, PermissionsRead, PermissionsEdit
FROM FieldPermissions
WHERE SObjectType = 'Opportunity'
AND Field = 'Opportunity.Discount__c'
AND ParentId IN (
SELECT PermissionSetId FROM PermissionSetAssignment
WHERE AssigneeId = '005XXXXXXXXXXXXXXX'
)
Any row with PermissionsRead = true means the user can read the field, object access permitting. No rows means FLS is your answer. It's precise, but you're still assembling the rest of the stack — placement, record type, sharing — by hand.
The shortcut, and its honest limit
This is the exact trace SchemaForce collapses into one answer. Point it at a field and it resolves the metadata layers — object access, field-level security across every profile, permission set, and permission set group, layout placement, and record type — and tells you, in one view, why a given kind of user can or can't see that field, across the whole org rather than one user at a time. It reads schema and configuration only; it never reads the contents of individual records, which is the whole point of running it against a production org.
That last detail also marks the limit worth stating plainly: the per-record sharing question — does this specific user have access to this specific record — is a data question, not a metadata one, so that stays a native check. SchemaForce tells you why the field is structurally visible or hidden for a user; it doesn't adjudicate one row's sharing. For the ninety percent of these tickets that turn out to be FLS, layout, or record type, that's the answer you were tracing toward anyway.
The checklist worth keeping
When the next "I can't see this field" lands, run it in this order:
- Field or record? Can they see other fields on the record, and this field on other records? This tells you which layer you're in before you touch anything.
- Object access. Read on the object through any profile or permission set?
- Field-level security. Use
View Summaryon the user orField Accesson the object. Remember it's additive — and watch for muting permission sets in a group. - Placement. Is the field on the layout or Dynamic Forms region for that profile and record type? Missing on the page but present in reports means it's a layout issue, not access.
- Record type and picklist values. Sees the field but not a value? That's record type.
- Sharing. If step one pointed at the record, this is where the real answer lives.
Work it top to bottom and you'll spend your time on the layer that's actually broken instead of the one that's easiest to open first.



