# Supabase "permission denied" error after October 30, 2026: a plain-English fix for Lovable and Bolt beginners

URL: https://buildstackweekly.com/supabase-permission-denied-fix
Updated: October 24, 2026

A new table in Supabase can throw permission denied after October 30, 2026, even when the row rules look fine. Supabase stopped showing new public tables to the Data API until you grant access. Tables you already had keep working. I'd grant the roles, turn row security on, and write a rule so each signed-in person only reads their own rows.

Don't open the whole table to everyone. A policy that uses true lets any role with a grant read every row. The rule I'd use checks auth.uid() against a user_id column, and that column has to exist.

This comes from Supabase's changelog and the Data API docs, checked on October 24, 2026. New projects started getting this on May 30, 2026. Existing projects get it on October 30, 2026. Lovable Cloud is not confirmed on those pages.

## What changed

On October 30, 2026, Supabase applies this to every existing project. A new table in the public schema is not reachable from the Data API until you grant it. The Data API is the REST and GraphQL layer that supabase-js and the other client libraries call.

If your app talks to Postgres directly, with psql, an ORM, or a connection string, you can skip this. Grants and row security are two different checks. A missing grant gets rejected before any row rule runs. Row security itself did not change.

You could opt in earlier. April 28, 2026 added a checkbox at project creation. May 30, 2026 made the new behavior the default for new projects, rolled out over a few weeks. If you're reading this before October 30 and your project is older, you may not see the error yet. The SQL below is the same either way.

## Who has to act

You need to do something if the app reads or writes public tables through the Data API. That includes supabase-js, the client libraries, and calls to the REST or GraphQL endpoints. You also need to act if a migration creates a public table and forgets the grant.

Same story if an AI coding tool, the CLI, or the Management API creates the table and expects it to be reachable right away. Supabase's changelog lists an email on October 23, 2026. It is the final notice, one week out, to owners and admins of active projects.

No Lovable or Bolt page in these sources says Lovable Cloud is affected. If a tool creates a new public table and skips the grant, Supabase puts that pattern in the group that has to act. I wouldn't tell you Lovable Cloud is on the list.

## The error you'll see

PostgREST returns this when the grant is missing. The code is 42501. Clients sometimes show it as a 401 or a 403. The SQL state is still 42501.

The hint names the role and the grant. In the sample it is select for anon. Yours can name a different role. Use the hint, then keep going. A grant by itself is not the whole fix.

```
{
  "code": "42501",
  "message": "permission denied for table your_table",
  "hint": "Grant the required privileges to the current role with: GRANT SELECT ON public.your_table TO anon;"
}
```

## Fix it in the dashboard

Open the project in the Supabase dashboard. Grants live under Integrations, then Data API. That screen is where you expose a table, or change who can select, insert, update, and delete. In the Data API settings, turn off Automatically expose new tables if you want new tables to stay hidden until you grant them.

Row security is under Database, then Policies. Select Enable RLS. Tables you create in the dashboard already have row security on. Tables created in the SQL Editor, or by another tool, need that switch. If Lovable or Bolt created the table, I'd run the SQL in the next section instead of guessing at clicks.

## Fix it with SQL

Supabase says to treat the grant, row security, and the policy as one unit. Run it in the SQL Editor. Swap your_table for the real table name. The select policy assumes a user_id column. If your column has another name, use that name. If the table has no user column, this policy will not match your rows.

The first grant lets signed-out visitors reach the table for select. With row security on, and no policy for them, those reads come back empty. They do not get every row. service_role bypasses row security, so keep that key on the server.

```
grant select on public.your_table to anon;
grant select, insert, update, delete on public.your_table to authenticated;
grant select, insert, update, delete on public.your_table to service_role;

alter table public.your_table enable row level security;

create policy "users can read their own rows"
  on public.your_table
  for select
  to authenticated
  using (auth.uid() = user_id);
```

## Add a policy for each write

The policy above is only for select, and only for signed-in users. Postgres wants a separate policy for insert, update, and delete. An update also needs a select policy, or it will not behave. These three use the same own-row check from Supabase's row security guide. I would not write using (true) on a private table. That opens every row to the role you name.

```
create policy "users can add their own rows"
  on public.your_table
  for insert
  to authenticated
  with check ((select auth.uid()) = user_id);

create policy "users can update their own rows"
  on public.your_table
  for update
  to authenticated
  using ((select auth.uid()) = user_id)
  with check ((select auth.uid()) = user_id);

create policy "users can delete their own rows"
  on public.your_table
  for delete
  to authenticated
  using ((select auth.uid()) = user_id);
```

## Questions

### Does this break tables I already have?

No. Existing tables keep their current grants and stay reachable. The break is a new table in public, created without a grant, after the setting is on. New projects started getting that default on May 30, 2026. Existing projects get it on October 30, 2026.

### What does the "permission denied" error look like?

Code 42501. The message is permission denied for table, plus your table name. The hint shows a grant for the role that was missing. A client may call that a 401 or a 403. The SQL state is still 42501.

### Should I turn off row security to make the error go away?

No. A missing grant fails before row security runs. Turning row security off, or adding a policy that uses true, exposes rows to any role that has a grant. Grant the role, leave row security on, and limit the policy to auth.uid() equals user_id.

### Is Lovable Cloud affected?

Lovable Cloud is not confirmed. Supabase says AI tools that create public tables without a grant are in the group that has to act. No Lovable page in these sources puts Lovable Cloud on this list. If your new table throws 42501, use the grant and the own-row policy anyway.

### Do I need a policy for writes?

Yes, if signed-in people should insert, update, or delete. The changelog example is select only. Insert uses with check. Update needs both using and with check, plus a select policy. Delete uses using. Each one should compare auth.uid() to user_id, and that column has to be on the table.

### What if I only connect with a database URL?

Then this change does not hit you. Direct Postgres, including psql, an ORM, or a connection string, skips the Data API. Tables in storage, auth, realtime, or a custom schema keep their current grants too.

## Related

- [Issue 0](https://buildstackweekly.com/issues/0)
- [Best vibe coding tools](https://buildstackweekly.com/best-vibe-coding-tools)
- [Lovable vs Bolt vs v0](https://buildstackweekly.com/lovable-vs-bolt-vs-v0)
- [Best AI App Builder for Beginners (2026)](https://buildstackweekly.com/best-ai-app-builder)
- [Lovable vs Cursor for Beginners (2026): Which Should You Use?](https://buildstackweekly.com/lovable-vs-cursor)
- [Best AI landing page builder](https://buildstackweekly.com/best-ai-landing-page-builder)
- [Supabase vs Firebase: Which Is Cheaper? (2026)](https://buildstackweekly.com/supabase-vs-firebase)
- [Best database for vibe coders](https://buildstackweekly.com/best-database-for-vibe-coders)
- [Cursor vs Claude Code](https://buildstackweekly.com/cursor-vs-claude-code)
- [Subscribe](https://buildstackweekly.com/#signup)
