{"record":{"id":"723ec03cd810d8e9","repo":"supabase/supabase","slug":"the-user-does-not-exist","errorCode":null,"errorMessage":"The user does not exist","messagePattern":"The user does not exist","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/studio/lib/api/apiAuthenticate.ts","lineNumber":48,"sourceCode":"  }\n}\n\n/**\n * @returns\n *  user with only id prop or detail object. It depends on requireUserDetail config\n */\nexport async function fetchUserClaims(req: NextApiRequest): Promise<JwtPayload> {\n  const token = req.headers.authorization?.replace(/bearer /i, '')\n  if (!token) {\n    throw new Error('missing access token')\n  }\n  const { claims, error } = await getUserClaims(token)\n  if (error) {\n    throw error\n  }\n\n  if (!claims) {\n    throw new Error('The user does not exist')\n  }\n\n  return claims\n}\n","sourceCodeStart":30,"sourceCodeEnd":53,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/lib/api/apiAuthenticate.ts#L30-L53","documentation":"Thrown after getUserClaims returns no error but also no claims object — meaning the token was syntactically processed but resolved to no known user. Distinct from [183] (no token at all) and from a token-parse error; here the JWT is present but the user lookup is empty.","triggerScenarios":"A request carries a bearer token, but the token is for a deleted/unknown user, an expired/revoked session that still parses, or a token minted by a different auth instance. getUserClaims succeeds without error yet yields claims === null/undefined.","commonSituations":"User account was deleted but the client still holds an old JWT; auth provider keys rotated so the token verifies against the wrong audience; a stale localStorage session survives across a user-merge or org migration.","solutions":["Force a fresh session on the client: call supabase.auth.signOut() then re-authenticate, so a new JWT is issued.","Verify the user still exists in the auth.users table and the token's sub matches an active account.","Check that AUTH_JWT_SECRET / JWKS config on the server matches the issuer of the token."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Client-side: proactively refresh before assuming the session is valid\nconst { data: { session } } = await supabase.auth.getSession()\nif (!session?.user) {\n  // force re-login instead of sending a doomed request\n}","typeGuard":"const hasValidClaims = (c: unknown): c is { sub: string } =>\n  typeof c === 'object' && c !== null && typeof (c as any).sub === 'string'","tryCatchPattern":"try {\n  const claims = await fetchUserClaims(req)\n} catch (e) {\n  if (e instanceof Error && e.message === 'The user does not exist') {\n    // prompt re-auth; the account is unknown or the token is stale\n    return res.status(401).json({ error: { message: 'Re-authentication required' } })\n  }\n  throw e\n}","preventionTips":["Sign users out and back in after account merges/deletions.","Keep server-side JWT secret/JWKS in sync with the auth issuer.","Treat 'claims present but null' as a hard re-auth signal, not a retry."],"tags":["authentication","authorization","user-not-found","jwt"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}