## Role is not allowed Confirm that the selected table has an endpoint for the exact operation and that the endpoint includes the server-resolved role key. `NONE` is an explicit deny; an absent role is also rejected. ## No allowed fields Check the intersection of requested fields, `allowed`, and `disallowed`. For joined fields, inspect the policy on the joined table as well. ## Policy does not match Inspect resolved `$user` and `$data` values, table qualification, operator shape, and the logical combination of request filters with policy filters. ## Unexpected row filtering Remember that request and policy `where` expressions are combined. Temporarily reduce the case to one condition at a time in a non-production test environment. ## Mutation rejects valid data Verify the payload shape, whether `data` is an object or array, and whether transition logic compares the intended `$data` field to the correct current column. ## Join fails Only `INNER` and `LEFT` are exported join types. Confirm that both table names exist in the structure, every field exists in the Drizzle schema, and the role may access joined fields. ## Trigger does not run Check the trigger type, endpoint placement, and whether `disable_triggers` is enabled. Nested trigger queries may intentionally disable triggers to avoid recursion. ## Phase order is surprising Queries inside a `TRANSACTION` phase run sequentially. Separate top-level phases are constructed and executed through `Promise.all`; do not rely on ordering between them. ## Debugging checklist 1. Reproduce with one table, endpoint, role, and field. 2. Validate the raw request against `StructuredQuery`. 3. Verify the authenticated user and role created by the server. 4. Inspect the relevant endpoint permission object. 5. Remove joins and triggers, then reintroduce them individually. 6. Run the closest repository test or add a denied-path regression test. 7. Capture internal errors securely without returning them to clients. [← Security](Security) · [Develop VoidQL →](Develop-VoidQL)