Supabase query returns an empty list, but the data is in the table
You can see rows in the Supabase Table Editor, but your app shows nothing and there is no error. Almost always a missing SELECT policy or a filter mismatch.
Why it happens
When Row Level Security is on and there is no SELECT policy that matches the user, Supabase does not return an error. It just returns an empty array, because from the user's point of view, there are no rows they are allowed to see.
The Table Editor and SQL editor bypass RLS, which is why you can see the data there.
Other causes: the query runs before the user session is loaded (so it runs as anon), a filter like .eq('user_id', user.id) uses the wrong column or an undefined value, or the app points at a different Supabase project than the one you are looking at.
How to fix it, step by step
- In Authentication → Policies, check the table has a SELECT policy for the role your users have (anon for public data, authenticated for logged-in users).
- Add a SELECT policy, e.g. USING (true) for genuinely public data like a product list, or USING (auth.uid() = user_id) for personal data.
- In the browser Network tab, find the request to /rest/v1/<table> and check the filters in the URL and the project URL.
- Make sure the query runs only after the session has loaded, so it uses the logged-in user.
- Log the error object too: const { data, error } = await ...; empty data with a null error points to RLS.
Paste-ready prompt for Lovable
My Supabase query for "<table>" returns [] even though the table has rows, and there is no error. Please: 1. Check the RLS policies on this table and add the right SELECT policy (public data: USING (true); personal data: USING (auth.uid() = user_id)). 2. Make sure the query waits for the auth session before running. 3. Verify the column names and filter values in the query match the table. 4. Log both data and error from the query in development. Keep RLS enabled.
FAQ
Why no error message?
RLS works like a filter. Rows you are not allowed to see are simply left out, so the result is empty rather than an error.
Should I use the service_role key to get around it?
Never in browser code. It bypasses all security and anyone could steal it. Fix the policy instead.
Still broken?
Get a free diagnosis by email within 24 hours. Fixed or refunded.
Get a free diagnosisOr get the weekly fix digest:
Free: the Vibe-Code Fix Checklist.