Common errors · Supabase (Lovable, Bolt, any client)
Supabase: new row violates row-level security policy
Cause RLS is on and no INSERT policy accepts the row your app sends (often user_id is not auth.uid(), or the session is not ready yet).
Fix Add an insert policy tied to auth.uid(), let the database fill user_id, and add UPDATE/SELECT policies if you upsert or select after insert.
Have it fixed for you, 290 EURSee the fix step by step
The insert works in the SQL editor and fails from the app. That is expected: the SQL editor runs as the postgres role and skips RLS, your app runs as anon or authenticated and does not.
Where it breaks
Which case is yours?
- RLS is enabled on the table and there is no INSERT policy whose WITH CHECK clause is true for the row you send.
- Most often the row carries a user_id that does not equal auth.uid(), or the request is sent before the session exists, so auth.uid() is null.
- An upsert needs both an INSERT and an UPDATE policy. A select after insert (.insert().select()) also needs a SELECT policy.
The fix, step by step
- Check who the request runs as. In the browser, log the session right before the insert: if it is null, the request is anonymous.
const { data: { session } } = await supabase.auth.getSession(); console.log(session?.user.id); - Add an insert policy tied to the signed-in user, and let the database fill user_id so the client cannot send a wrong one.
alter table profiles alter column user_id set default auth.uid(); create policy "insert own row" on profiles for insert to authenticated with check (user_id = auth.uid()); - If you use upsert or .select() after the insert, add the matching policies.
create policy "read own row" on profiles for select to authenticated using (user_id = auth.uid()); create policy "update own row" on profiles for update to authenticated using (user_id = auth.uid()) with check (user_id = auth.uid()); - Never fix it by disabling RLS or by putting the service_role key in the frontend. Both make every row readable and writable by anyone who opens the browser console.
How to check it is fixed
Sign in as a test user, insert a row: it succeeds. Sign in as a second user and try to read the first user's row: you get an empty result, not an error.
Delivery example for this error
- insert ... user_id: undefined+ alter column user_id+ set default auth.uid();- Root cause: RLS is on and no INSERT policy accepts the row your app sends (often user_id is not auth.uid(), or the session is not ready yet).
- Change made: Add an insert policy tied to auth.uid(), let the database fill user_id, and add UPDATE/SELECT policies if you upsert or select after insert.
- Sign in as a test user, insert a row: it succeeds.
- Sign in as a second user and try to read the first user's row: you get an empty result, not an error.
Illustrative: the real diff is written against your repository. Full sample report
Still stuck on your own code?
Send the repository and the exact error. Fix: 290 EUR all taxes included, delivered within 72 hours, refunded if not resolved.
Not sure it is this error? Ask for a free written diagnosis, no card needed.