“new row violates row-level security policy” (42501)

You'll see:
  • Error: new row violates row-level security policy for table "…"
  • Postgres error code 42501
  • Reads work but saving data fails after deploying

Why it happens

RLS is on (good) but there is no INSERT/UPDATE policy that allows this user to write this row — or the user isn't signed in on the deployed site, so auth.uid() is null.

How to fix it

  1. Add an INSERT policy with a WITH CHECK clause

    create policy "Users insert own rows"
    on public.todos for insert
    to authenticated
    with check ( (select auth.uid()) = user_id );
  2. UPDATE needs a SELECT policy too

    In Postgres an UPDATE first has to see the row, so you need a matching SELECT policy in addition to the UPDATE policy.

    create policy "Users update own rows"
    on public.todos for update
    to authenticated
    using ( (select auth.uid()) = user_id )
    with check ( (select auth.uid()) = user_id );
  3. Make sure the row's user_id is set

    Your insert must send user_id equal to the signed-in user's id (or give the column a default of auth.uid()).

    alter table public.todos
      alter column user_id set default auth.uid();
  4. Confirm login works on the live domain

    If sign-in silently fails on your new domain, see the OAuth redirect guide — a logged-out user will hit this error on every write.

Common with:

Related fixes