Tous les articles
Supabase 6 min 20 mars 2026

Comment résoudre l'erreur Supabase RLS infinite recursion

L'erreur 'infinite recursion detected in policy for relation' bloque des centaines de projets vibe-codés. Voici la cause exacte et le fix en 5 minutes.


Si ton projet Supabase affiche infinite recursion detected in policy for relation "profiles", tu n'es pas seul. C'est l'une des erreurs les plus fréquentes en vibe coding, et elle bloque le chargement complet de l'application.

Pourquoi cette erreur se produit

Supabase utilise Row Level Security (RLS) pour contrôler qui peut lire quelle donnée. Le problème apparaît quand une politique RLS sur une table fait référence à la même table — créant une boucle infinie.

Exemple typique : tu as une table profiles et une politique qui vérifie le rôle de l'utilisateur en faisant une requête sur... profiles :

CREATE POLICY "Users can read own profile"
ON profiles FOR SELECT
USING (
  auth.uid() = id
  OR (
    SELECT role FROM profiles  -- ← BOUCLE ICI
    WHERE id = auth.uid()
  ) = 'admin'
);

Supabase évalue cette politique → lit profiles → évalue la politique → lit profiles... à l'infini.

La solution : utiliser auth.jwt() ou une fonction SECURITY DEFINER

Il y a deux approches selon ton cas :

Option 1 — Lire le rôle depuis le JWT (recommandé)

Si tu stockes le rôle dans les claims JWT (ce que Supabase permet via les custom claims), tu peux y accéder directement :

CREATE POLICY "Users can read own profile"
ON profiles FOR SELECT
USING (
  auth.uid() = id
  OR (auth.jwt() ->> 'role') = 'admin'
);

Pour peupler ce claim, ajoute une fonction trigger qui met à jour le JWT après chaque login via supabase_auth_admin.update_user_by_email().

Option 2 — Créer une fonction SECURITY DEFINER

Une fonction SECURITY DEFINER s'exécute avec les droits du créateur (postgres), contournant le RLS :

CREATE OR REPLACE FUNCTION public.get_my_role()
RETURNS text
LANGUAGE sql
SECURITY DEFINER
STABLE
AS $$
  SELECT role FROM public.profiles WHERE id = auth.uid();
$$;

-- Dans ta politique, utilise la fonction :
CREATE POLICY "Users can read own profile"
ON profiles FOR SELECT
USING (
  auth.uid() = id
  OR public.get_my_role() = 'admin'
);

Vérifier que le RLS est bien configuré

Après avoir corrigé, teste dans le SQL Editor de Supabase :

-- Simuler un user standard
SET LOCAL role TO authenticated;
SET LOCAL request.jwt.claims TO '{"sub": "ton-user-id"}';
SELECT * FROM profiles LIMIT 1;

Si ça retourne sans erreur, le fix est bon.

Autres causes de l'erreur

  • Politique sur public.users qui référence une autre table avec une politique similaire
  • Jointures dans une politique entre deux tables qui s'appellent mutuellement
  • Vues matérialisées avec RLS activé et politiques récursives

Résumé rapide

Checklist pour corriger l'erreur RLS :

  1. Identifier la politique qui fait une auto-jointure
  2. Remplacer par auth.jwt() si le rôle est dans les claims
  3. Sinon, créer une fonction SECURITY DEFINER
  4. Tester via le SQL Editor en simulant le contexte user

Si ton projet a plusieurs tables avec des politiques inter-dépendantes, le bug peut être plus difficile à tracer. C'est exactement ce genre de problème que les experts Last 20% résolvent — avec un rapport expliquant exactement ce qui se passait.


Tu as ce problème sur ton projet ?

Un expert Last 20% peut le résoudre pour toi en 24h. Diagnostic gratuit, garanti.

Diagnostic gratuit