Demo, all content is generated
Question

Bolt + Supabase: new row violates row-level security policy for table "profiles"

Solved · 412 views · asked by mcflyy · edited

Signup works, user appears in Auth. Then my code inserts the profile row and I get:

{
  code: "42501",
  message: 'new row violates row-level security policy for table "profiles"'
}

Bolt made this policy:

create policy "Users can insert own profile" on profiles
  for insert with check (auth.uid() = id);

Looks right to me?

What I’ve tried

Asked Bolt to fix, it suggested disabling RLS on profiles. I did not do that because I read that's bad. Tried logging in first and then inserting, same error.

Comment
Is email confirmation turned on in your Auth settings? jb_supa · edited
no idea, where do I see that mcflyy · edited

3 answers

Marked as helpful by the asker
jb_supa · edited

The policy is fine, the timing isn't. If "Confirm email" is on in Supabase Auth, signUp() returns a user but no session. Your insert right after runs as anon, so auth.uid() is null and the check fails.

Cleanest fix: create the profile in the database with a trigger, so the client never has to:

create function public.handle_new_user()
returns trigger language plpgsql security definer set search_path = ''
as $$
begin
  insert into public.profiles (id, username)
  values (new.id, new.raw_user_meta_data->>'username');
  return new;
end;
$$;

create trigger on_auth_user_created
  after insert on auth.users
  for each row execute function public.handle_new_user();

Pass username via options.data in signUp. Remove the client-side insert.

And good call not disabling RLS.

Comment
Confirm email was on yes. Trigger works, profile appears on signup now. mcflyy · edited
+1 on the trigger. The set search_path = '' bit matters, keep it. hannah_reyes · edited
amir_h · edited

Side note for later: once you have that trigger, drop the insert policy on profiles entirely. Users never need to insert their own profile then, one less door open.

Comment
arash · edited

Had exactly this. For testing you can turn off email confirmation in the Auth settings so signups get a session immediately, but switch it back on before real users arrive.

Comment