# Your AI-built app works in the builder but breaks on deploy with a Supabase "permission denied" error. Here is why, and how to fix it.

> Source: <https://dev.to/toritic/your-ai-built-app-works-in-the-builder-but-breaks-on-deploy-with-a-supabase-permission-denied-45ik>
> Published: 2026-07-13 05:08:10+00:00

You built an app in Lovable, Bolt, v0, or Cursor. It worked perfectly in the preview. You deployed it, opened the live URL, and now half the screen is empty or you see something like:

```
permission denied for table profiles
code: 42501
```

or your data loads as `null`

and the console shows `getUser()`

returned nothing. The frustrating part is that nothing changed in your code between the working preview and the broken deploy. So what happened?

This is one of the most common failures we see, and it is not random. AI app builders generate a working front end fast, but they often leave the security boundary between your app and your database half finished. Two things are usually true at once:

Row Level Security (RLS) is on. Supabase enables RLS so a table can only be read or written by the right user. That is correct and you want it. Your policy probably says something like "a row is visible when `auth.uid() = user_id`

".

The request reaching Supabase in production is anonymous. In the builder preview, the request often carried your session, or ran with elevated access, so RLS let it through. In the real deploy, the server is calling Supabase without the logged-in user's identity attached. So `auth.uid()`

is null, the policy does not match, and Supabase correctly refuses with `42501 permission denied`

.

In plain terms: your security rules are working, but your app is knocking on the door without showing its ID.

Before changing anything, keep the exact error text. Then check, in order:

`SUPABASE_URL`

and the anon key, produces the same symptom.The real fix is to make the request carry the user's identity, so `auth.uid()`

is populated when RLS checks it. In a Next.js and Supabase app that usually means:

`auth.uid()`

to the row's user column. Do not "fix" this by turning RLS off.Then rerun the exact user action that failed and confirm it works against the same Supabase project and domain that broke.

The tempting shortcut is to disable RLS or to use the service role key in the browser so the error disappears. Please do not. Disabling RLS makes every row in that table readable and writable by anyone on the internet, and putting the service role key in client code hands a stranger full control of your database. The error is annoying, but it is protecting you.

If you are non-technical and this already reads like another language, that is normal. This is exactly the kind of thing an AI builder cannot finish for you, because it lives in the boundary between auth, the database, and the deploy.

We run a service for this called Vibe-Code Rescue. You paste the error and get a free, plain-language diagnosis of what is wrong and what it takes to fix. If you want it fixed, it is a flat rate, you pay only after the fix is verified working, and you keep clean code you own. No subscription, no retainer.

Free diagnosis here: [https://rescue.ticassociation.com](https://rescue.ticassociation.com)

A TIC Association creation.
