Supabase RLS Errors in Lovable and Bolt Apps (and How to Fix Them Safely)

Quick answer: Fix "new row violates row-level security policy" and empty query results in Lovable and Bolt apps using Supabase. Includes copy-paste SQL policies.

The error

new row violates row-level security policy for table "todos"

Postgres error code 42501. A related symptom: select returns [] with no error even though the table has rows.

Why it happens

When Row Level Security (RLS) is enabled and no policy allows an action, Supabase blocks it. Common causes in AI-built apps:

Fixes

1. Add owner-based policies (run in the Supabase SQL editor)

alter table public.todos enable row level security;

create policy "Users read own todos" on public.todos
  for select to authenticated using ((select auth.uid()) = user_id);

create policy "Users insert own todos" on public.todos
  for insert to authenticated with check ((select auth.uid()) = user_id);

create policy "Users update own todos" on public.todos
  for update to authenticated
  using ((select auth.uid()) = user_id) with check ((select auth.uid()) = user_id);

create policy "Users delete own todos" on public.todos
  for delete to authenticated using ((select auth.uid()) = user_id);

2. Fill in user_id automatically

alter table public.todos alter column user_id set default auth.uid();

3. Make sure the user is actually signed in

const { data: { user } } = await supabase.auth.getUser();
if (!user) throw new Error('Not signed in');
await supabase.from('todos').insert({ title, user_id: user.id });

4. Don't "fix" it by disabling RLS or shipping the service_role key

The service_role key (and the newer sb_secret_... secret keys) bypasses RLS entirely. Keep it on the server only, and never put it in frontend code. The browser should only use the anon or publishable key.

Prompt to paste into Lovable/Bolt

Write Supabase RLS policies so authenticated users can only select, insert, update, and delete rows where user_id = auth.uid(). Don't disable RLS and don't use the service_role key in the client.

FAQ

Why do I get empty results instead of an error? RLS filters select results silently. With no policy, you get zero rows. Is a public read policy OK? Yes for public data: for select to anon, authenticated using (true).

Still stuck? Paste your exact error into the free Error Fixer to get a plain-English cause, the fix, and a prompt to paste back into your AI tool.

Get the free "10 Prompts That Fix Broken AI Code" pack

Join the FixKit AI newsletter: one short email a week with real errors from Cursor, Lovable, Bolt & Replit users and how to fix them. Unsubscribe anytime.

Newsletter signup powered by beehiiv. We only use your email to send the newsletter.