| name | record-access-troubleshooting |
| description | Diagnose why a user can or cannot see/edit a record: UserRecordAccess SOQL, Why Can a User Access This Record debug log, OWD, role hierarchy, sharing rules, manual/team/apex shares, implicit parent share. NOT for field-level security (use field-level-security-audit). NOT for designing sharing (use sharing-selection decision tree). |
| category | security |
| salesforce-version | Spring '25+ |
| well-architected-pillars | ["Security"] |
| tags | ["sharing","record-access","userrecordaccess","owd","troubleshooting"] |
| triggers | ["why can user see this record salesforce debug","userrecordaccess soql hasreadaccess hasedit","explain record access why user view edit","sharing rule not taking effect troubleshoot","manual share apex share missing record","owd private user cannot see record"] |
| inputs | ["User Id whose access is in question","Record Id in question","Expected access (view / edit / delete)","Object's OWD setting"] |
| outputs | ["UserRecordAccess diagnostic query","Sharing chain trace","Remediation recommendation"] |
| dependencies | [] |
| version | 1.0.0 |
| author | Pranav Nagrecha |
| updated | 2026-04-21T00:00:00.000Z |
Record Access Troubleshooting
Activate when a user reports "I can't see this record" or "Why can this user edit this record?" Troubleshooting record access means tracing the sharing chain: OWD → role hierarchy → ownership → sharing rules → teams → manual shares → Apex shares → implicit parent share. This skill gives a deterministic diagnostic flow using UserRecordAccess SOQL and the "Sharing" access debug tool, not guesswork.
Before Starting
- Gather specifics. User Id, Record Id, expected access (view/edit/delete), object OWD.
- Identify the object's OWD. Setup → Sharing Settings. Private / Public Read Only / Public Read/Write / Controlled by Parent.
- Check profile/permset modify-all. "Modify All Data" and "View All Data" bypass sharing entirely.
Core Concepts
UserRecordAccess (primary diagnostic)
SELECT RecordId, HasReadAccess, HasEditAccess, HasDeleteAccess,
HasTransferAccess, HasAllAccess, MaxAccessLevel
FROM UserRecordAccess
WHERE UserId = '005...' AND RecordId = '001...'
Returns the effective access result but not the reason. Run this first.
Explain Access button
On any record's Sharing detail page: "Why can this user access this record?" — lists the reason (Owner, Role Hierarchy, Sharing Rule X, Manual Share, Apex Managed Share, Implicit Parent). Available in Classic UI; Lightning has "Sharing Hierarchy."
Sharing reason chain (order Salesforce evaluates)
- Admin bypass. "View All Data" / "Modify All Data" / "View All" / "Modify All" on an object.
- Ownership. The record owner has full access (unless the role says otherwise).
- Role hierarchy. If enabled on the object, users above the owner's role inherit access.
- Sharing rules. Ownership- and criteria-based rules grant read or read/write.
- Teams. Account, Opportunity, Case teams.
- Manual shares. UI "Share" button.
- Apex managed shares.
__Share rows with RowCause.
- Implicit parent share. Child records on master-detail inherit parent access.
- Restriction rules. Filter DOWN access — user might have access via the above but restriction rule denies.
__Share objects
For every object with non-Public OWD, there's a <Object>__Share sharing table. Query it to see grants:
SELECT UserOrGroupId, AccessLevel, RowCause FROM Account__Share WHERE ParentId = '001...'