From 30 October 2026, Supabase changes how new tables work on every existing project. If you build with Lovable or another AI tool, the next table it adds may load nothing, and your app will show a "permission denied" error. Here's what's going on and how to fix it without opening up your data.
What changes
Until now, every new table in the public schema got read and write access for Supabase's three API roles straight away: anon (signed-out visitors), authenticated (signed-in users) and service_role (server code). That's why a new table "just worked" in your app.
From 30 October 2026, Supabase stops doing that on all existing projects. A new table in public gets no access for those roles until you grant it. New projects have worked this way by default since 30 May 2026. (Supabase changelog)
Two things stay the same:
- Existing tables keep their access. Tables you already have won't break because of this change.
- Row level security (RLS) works as before. Grants decide whether a role can touch a table at all. RLS decides which rows it can see. They're separate layers. (Securing your API)
If you use the Supabase CLI for local development, the [api].auto_expose_new_tables setting now defaults to false as well, so local projects behave the same way. (Supabase CLI PR #5524)
Who is affected
You're affected if your app talks to Supabase through supabase-js or the REST or GraphQL API, which is how Lovable apps work, and you (or your AI tool) create new tables in public after the change reaches your project.
You're not affected if your app only connects straight to Postgres with a connection string. (Supabase changelog)
How to recognise it
The usual pattern:
- You ask Lovable for a new feature, and it adds a table.
- The new page loads empty, or saving fails, or you see an error toast.
- Older pages still work fine.
In the browser console or network tab, the request returns an error like this:
{
"code": "42501",
"message": "permission denied for table orders",
"hint": "Grant the required privileges to the current role with: GRANT SELECT ON public.orders TO anon;"
}The parts to look for are the code 42501 and the words permission denied for table, followed by your table name.
One catch: if the message says new row violates row-level security policy instead, that's a different problem. It means the table's RLS policies blocked the row. The fix below won't help with that one.
The safe fix
The fix comes in three parts, and they belong together in one migration. Supabase recommends the same thing. (Securing your API)
1. Grant only what the app needs, on that table only, to the right role.
Most Lovable apps have users sign in, so the role is usually authenticated. Only grant the actions the app actually does on that table.
grant select, insert, update, delete on table public.orders to authenticated;Only grant to anon if signed-out visitors really need to see the table, for example a public product list. Even then, read access is usually all they need:
grant select on table public.products to anon;2. Make sure RLS is on.
alter table public.orders enable row level security;Running this is harmless if RLS is already on.
3. Make sure there are policies that match how the app uses the table.
For a table where each user only sees their own rows:
create policy "Users can read their own orders"
on public.orders for select to authenticated
using ((select auth.uid()) = user_id);
create policy "Users can add their own orders"
on public.orders for insert to authenticated
with check ((select auth.uid()) = user_id);Why bother with steps 2 and 3? Because once a role has a grant, a table without RLS is open to anyone using that role. Supabase's docs warn about exactly this. (Securing your API) Without the grant, the API can't see the table. Without RLS, the grant lets everyone see everything.
If saving a row then fails with permission denied for sequence, the table uses a numbered ID. Grant usage on that one sequence to the same role.
What not to do
When the app is broken, these shortcuts are tempting. Don't use them:
- Don't grant access to every table in
public. A line likegrant ... on all tables in schema public to anon, authenticatedhands access to every table you have, including ones you meant to keep private. Supabase's changelog shows this bulk grant as a way to undo an early opt-in. It's not a fix for one broken table. - Don't change the default privileges back with
alter default privileges ... grant. That opens every future table automatically, which is the exact risk this change removes. - Don't turn RLS off to make the error go away. With RLS off and a grant in place, anyone holding your public API key can read and change every row.
- Don't grant write access to
anonunless signed-out visitors truly need to write to that table.
A prompt you can paste into Lovable
Replace TABLE_NAME with the table from the error message.
My app gets a Supabase error 42501 "permission denied for table TABLE_NAME". Supabase no longer grants API access to new tables automatically.
Please create a new Supabase migration that:
1. Grants only the privileges the app's code actually uses (select, insert, update, delete) on public.TABLE_NAME, and only to the authenticated role. Only grant select to anon if signed-out visitors must see this table. Never grant write access to anon.
2. Runs: alter table public.TABLE_NAME enable row level security;
3. Checks the existing policies on public.TABLE_NAME and adds any missing ones so each user can only access their own rows (or whatever matches how this table is used). Don't duplicate policies that already exist.
Do not grant on all tables in the public schema, do not use alter default privileges, do not grant to PUBLIC, and do not disable row level security. Don't change any other tables. Tell me exactly which grants and policies you added.After Lovable applies the migration, reload the page that failed and try the action again.