Supabase: infinite recursion detected in policy
infinite recursion detected in policy for relation "profiles"
In short: An RLS policy on a table queries that same table (or a view that does), so Postgres loops until it stops the query.
Why it happens
Row Level Security policies run as part of every query on the table. If a policy's USING or WITH CHECK clause reads from the same table, that read re-enters the policy, which reads again, and Postgres raises 42P17. A common AI-generated pattern is a profiles policy that looks up the current user's team_id with select team_id from profiles where id = auth.uid(). Policies on views, or helper functions that are not SECURITY DEFINER, can trigger the same loop. Wrapping auth.uid() in a subselect is a performance tip, not a fix for recursion.
How to fix it
- Find the policy named in the error (Database → Policies, or
pg_policiesfor that table) and look for a subquery or function that reads the same table. - Move the self-lookup into a small
SECURITY DEFINERfunction that only returns the current user's own row (for example theirteam_id), withset search_path = publicandstable. Because it bypasses RLS, keep the function tight and grantexecuteonly toauthenticated. - Change the policy to call that function instead of querying the table directly.
- Or avoid the loop another way: store the needed value on a different table (like
members) whose policies don't read back from the first table. - Re-run the query as a signed-in user, not in the Table Editor, which bypasses RLS.
Example
create or replace function public.my_team_id()
returns uuid
language sql
stable
security definer
set search_path = public
as $$
select team_id from public.profiles where id = auth.uid()
$$;
revoke all on function public.my_team_id() from public;
grant execute on function public.my_team_id() to authenticated;
create policy "Users read teammates"
on public.profiles for select to authenticated
using ( team_id = public.my_team_id() );
Copy-paste fix prompt
I'm getting this error in my app: infinite recursion detected in policy for relation "profiles" [Paste the full error, stack trace, and the file it points to here] Likely cause: An RLS policy on a table queries that same table (or a view that does), so Postgres loops until it stops the query. Task: Find the RLS policy on the table in the error that queries the same table (or a non-definer function that does). Replace that self-lookup with a tight SECURITY DEFINER helper or a non-recursive table. Don't disable RLS. Rules: - First explain the root cause in 2 sentences and list the files you'll change. - Make the smallest change that fixes it. Don't refactor unrelated code. - Don't disable security or checks (RLS, auth, signature verification, type checking, CORS allow-all) to make the error disappear. - Never print or hard-code secret keys. - Finish by telling me exactly how to verify the fix.
Common with: Lovable, Bolt, Cursor, v0. Last reviewed 2026-11-15.