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
-
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 ); -
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 ); -
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(); -
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.