Fixes › Database / Supabase RLS
new row violates row-level security policy for table
The error
new row violates row-level security policy for table "profiles" (code 42501)
Why it happens
An INSERT or UPDATE was attempted on a table with RLS enabled, but no INSERT policy (WITH CHECK) allows it, or the row's owner column doesn't match auth.uid(). Common when the app inserts before the user is signed in, or forgets to set user_id.
How to fix it
- Confirm the user is authenticated when the insert runs.
- Set the owner column (user_id) to the signed-in user's id, or give it a default of auth.uid().
- Add an INSERT policy: create policy "insert own" on public.profiles for insert to authenticated with check (auth.uid() = user_id);
- If you upsert, you also need an UPDATE policy.
Fix prompt (paste into Lovable, Bolt, Cursor, Replit or v0)
Inserts into <TABLE> fail with 'new row violates row-level security policy'. Keep RLS on. Add an INSERT policy for authenticated users WITH CHECK (auth.uid() = user_id), set the user_id column default to auth.uid(), add a matching UPDATE policy if we upsert, and make sure the insert only runs after sign-in. Give me the SQL migration.
FAQ
Can I use the service_role key in the browser to bypass this?
Never. The service_role key bypasses all RLS and must only live on a server.
What is WITH CHECK?
The condition new or changed rows must satisfy; USING filters existing rows.
Related fixes
- Supabase query returns an empty array (no error)
- Supabase Edge Function fails with CORS or 'Failed to send a request'
- Supabase Storage upload fails: new row violates row-level security policy (403)
- Postgres error: relation "public.xyz" does not exist
Want the full checklist for this area? Get a Fix Kit ($29)
Featured slot available: reach thousands of vibe coders. Sponsor this week →
Get one new fix a week
Free newsletter: the newest breakages in Lovable, Bolt, Cursor, Replit and v0 apps, with paste-in fixes.
We only use your email to send the newsletter. Unsubscribe any time. See privacy.