"new row violates row-level security policy" — what it means
Good news, badly worded: this error is your database refusing an unauthorised write.
What it means
Supabase rejected an INSERT or UPDATE because no Row Level Security policy permitted it. The full message is usually: new row violates row-level security policy for table "…". The database is doing exactly what it was told.
Why it happens in AI-built apps
- RLS was enabled but only a SELECT policy was written — reads work, writes are refused.
- The INSERT policy has no WITH CHECK clause. USING governs which rows you may see; WITH CHECK governs which rows you may create.
- The row's user_id is not being set to the current user, so the ownership check fails on a row you genuinely own.
- The write runs before the session is ready, so auth.uid() is null at that moment.
Is this error actually a problem?
Check it yourself
Confirm RLS is denying, not just failing
- 1Open your app, F12, Network tab, and copy the apikey header from any *.supabase.co request.
- 2Run: curl "https://YOUR-PROJECT.supabase.co/rest/v1/YOUR_TABLE?select=*&limit=3" -H "apikey: YOUR_ANON_KEY"
- 3An empty array [] means reads are correctly denied — your write error is a policy gap, not an open table.
- 4Rows coming back means the table is readable by anyone, which is a much bigger problem than the write error you came here for.
Fix it
Copy this into your AI coding tool
I get "new row violates row-level security policy" on a Supabase table.
1. Show me the table's current policies, separating USING from WITH CHECK,
and tell me which command (INSERT or UPDATE) is being refused.
2. Explain which specific condition my write fails.
3. Add the correct policy so the signed-in user can write their own rows:
CREATE POLICY "insert own rows" ON <table> FOR INSERT
WITH CHECK ((select auth.uid()) = user_id);
and the matching UPDATE policy with both USING and WITH CHECK.
4. Check that my insert actually sets user_id to the current user; if the
client omits it, add a default of auth.uid() on the column.
5. Confirm auth.uid() is non-null at the point of the write — if the call
happens before the session loads, fix the ordering.
Do NOT disable RLS and do NOT write a policy of WITH CHECK (true). If the
only way to make my write pass is to allow everyone, tell me that instead
of doing it.This is one check out of 40+
Paste your site address and we run the whole list from the outside — leaked keys, open databases, unprotected pages — then hand you one prompt that fixes what we find. Free, about 30 seconds, no signup.
Check my site — free