Skip to content

Supabase query problemSupabase select returns an empty array, but the data is there

The table editor shows rows, yet the app’s query returns an empty array and no error. With row level security on, Supabase only returns the rows a policy allows, and it filters the rest out quietly. Here are the usual reasons in Supabase’s words, or hand it over at a fixed price.

Short answer

Check that the table has a select policy: with RLS on and no policy, the API returns no data to the browser key. Then check who the request runs as: a signed-out user or an expired session matches no rows in a policy based on auth.uid(). If you get error 42501 instead of an empty array, the role is missing a grant.

Why the query returns no rows, and the fix

  1. 01

    RLS is on and there is no select policy

    “Once RLS is enabled, no data is accessible through the API when using a publishable key, until you create policies.” Supabase, Row Level Security

    Turning on row level security without adding policies blocks every row for the browser key. Add a select policy that matches who should read the data, such as each user reading their own rows.

    create policy "Users can view their own profile."
    on profiles for select
    to authenticated
    using ( (select auth.uid()) = user_id );
  2. 02

    The request runs signed out

    “This means that a policy like: USING (auth.uid() = user_id) will silently fail for unauthenticated users” Supabase, Row Level Security

    If the query runs before the session loads, or after it expires, auth.uid() is null and a policy comparing it to user_id never matches. Supabase recommends checking for a signed-in user explicitly in the policy so the intent is clear.

  3. 03

    The rows don’t match the policy

    “Think of a policy as adding a WHERE clause to every query.” Supabase, Row Level Security

    A policy works like a filter added to every query. Rows inserted without a user_id, or with another user’s ID, never come back for this user. In our experience this often happens with rows created by a seed script or a server using the service role key.

  4. 04

    An error, not an empty array, means a missing grant

    “A missing grant raises a 42501 error before any policy runs.” Supabase, Row Level Security

    If the query fails with 42501 instead of returning an empty array, the role lacks permission on the table itself, before any policy runs. Supabase says to check grants before changing the policy.

Checked against the vendor’s docs on : Supabase docs: Row Level Security.

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Supabase PGRST116 from .single() · RLS is on: is the data safe now? · Supabase OAuth provider disabled · Supabase Invalid login credentials

Questions

More on this error

Should we turn RLS off to get the data back?

No. Without RLS, the table is open to anyone who has your browser key. Add a policy that lets the right users read the right rows instead.

Why does it work with the service role key?

Supabase says a secret key bypasses RLS only when the request carries no user access token, so a server request without one sees every row. Supabase also says never to use a secret key in the browser. It hides policy problems while you test, so test as a signed-in user as well.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; we reply by email, usually within one business day.