AccountedPro - The Access Simulator

The Access Simulator (/app/access-simulator) answers most “why can / can't they…” questions in one click. Enter a user and a DocType (and an optional record), and it shows:

  • the row condition (the compiled WHERE for that user);
  • the visible / total counts;
  • the cascade sources feeding this DocType;
  • for one record: the opening doors, the granted actions, and the field access.

Toggle Show compiled SQL in the builder to see what a single door compiles to. Between the two, most puzzles are settled without reading a line of code.

Troubleshooting

A person sees fewer records than expected

  • A per-user door excludes them. A door scoped Current user is IN (…) doesn't apply to people outside the list — good — but make sure they aren't relying on a door that no longer opens for them. With Default Deny on and every door's scope false, they see nothing (expected); with it off, they fall through to native / cascade.
  • A cascade Gate is filtering orphans. Under a Gate, a child with an empty / NULL link is excluded. The “missing” rows usually have no parent — fill the link or add a child-side door.
  • First match wins is shadowing. A restrictive door listed above a permissive one wins. Reorder with ⋮⋮, or switch to Best access wins.

“No permission for DocType” on an ordinary form

Almost always a core / meta DocType got governed. Frappe routes its dynamic-link machinery through permissions; if a meta DocType (DocType, DocField, Report, Property Setter, …) is wired, ordinary forms with a Dynamic Link field get denied. Don't add Access Rules for core / config DocTypes — the app ships a comprehensive never-govern list.

A whole list errors with a SQL syntax error

A saved scope compiled to invalid SQL — historically a linked-record filter in the wrong format (a Frappe filter dict instead of field / operator / value rows), which left a dangling AND. The compiler now drops blank sub-conditions; rebuild the filter with the + filter rows and use Show compiled SQL to confirm the door is well-formed before saving.

A masked form stays masked after navigating to an unmasked one

The Desk reuses one form view across documents. The client script resets on every refresh, so this shouldn't linger — if it does, it's a stale cached script; hard-refresh, and confirm the console shows the current enforce.js version.

A record opens masked / blank when it shouldn't (or a 500 with no error log)

  • No error log + a 500 is the fingerprint of a SQL error — the failing statement aborts before it can be logged. The engine's fail-safe wrappers log the real traceback and degrade instead of 500ing; reproduce, then read the log.
  • Fields wrongly hidden — check the door's profile default field access (a Blur / Hidden default is a hard cap) and whether an approved grant is expected to lift it.

An in / not in list matches nothing

The value is a comma-separated string. If the compiled SQL shows it split into single characters, the field name or format is off — the engine splits on commas, so a, b, c becomes IN ('a','b','c').

A custom report leaks masked fields

Raw frappe.db.sql / get_all bypass field redaction. Route the reads through readable_rows (see Developer reference).

Next: Developer reference.

Discard
Save
This page has been updated since your last edit. Your draft may contain outdated content. Load Latest Version

On this page

Review Changes ← Back to Content
Message Status Space Raised By Last update on