Start watching free

Error library · Empty lists from row-level security

Supabase returns an empty list in production (row-level security)

A page that should list orders, posts or bookings is empty. The rows are there in the Supabase table editor. Nothing looks broken; there is just no data.

Why it happens

Supabase’s row-level security decides which rows each signed-in person may read. With it switched on and no policy that matches, a read does not fail. It succeeds and returns nothing, so the app shows an empty list.

It works while you build because you are testing as the one user who created the rows, or because security was off on that table at the time.

Check it in a minute

  1. In Supabase, open the table and confirm the rows exist.
  2. Sign in to your live app as a different, ordinary user.
  3. If the list is empty for them and the browser shows the request succeeding with [], it is a missing read policy.

How to fix it

Give this to the AI that builds your app: Lovable, Bolt, Cursor, Claude Code or any other.

On the live app a list is empty although the rows exist in Supabase. Row-level security is on for the table and I think no SELECT policy lets the signed-in user read their rows.

1. Find the table this page reads and list its current row-level security policies.
2. Add a SELECT policy that lets a signed-in user read only their own rows (the column that holds the owner's user id = auth.uid()). If some rows are meant to be public, say so and add a separate policy for those.
3. Do not turn row-level security off and do not use the service-role key in the browser.
4. Check INSERT, UPDATE and DELETE on the same table and tell me which are missing a policy.

Show me the SQL before running it. After the fix, an ordinary signed-in user must see their own rows and nobody else's.

What Vigilia sees of this

  • The loud half: a save Supabase refuses (“new row violates row-level security policy”) is recognised at once, with no AI credits. See that page.
  • Requests answered 401 or 403 are raised from the first visitor.

What it can’t see: An empty list is the quiet half. The request succeeds and returns nothing, so no error is thrown and Vigilia has nothing to catch. If visitors click around a page that looks empty, their repeated clicks can show up as a frustration signal, but that is a hint, not a diagnosis.

Know before your users tell you

Vigilia watches your live app, explains what breaks in plain language, hands your AI the fix, and confirms it held with real visitors.

More from the error library