supabase/supabase · error · Error
The user does not exist
Error message
The user does not exist
What it means
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.
Source
Thrown at apps/studio/lib/api/apiAuthenticate.ts:48
}
}
/**
* @returns
* user with only id prop or detail object. It depends on requireUserDetail config
*/
export async function fetchUserClaims(req: NextApiRequest): Promise<JwtPayload> {
const token = req.headers.authorization?.replace(/bearer /i, '')
if (!token) {
throw new Error('missing access token')
}
const { claims, error } = await getUserClaims(token)
if (error) {
throw error
}
if (!claims) {
throw new Error('The user does not exist')
}
return claims
}
View on GitHub (pinned to beee91b9c2)
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.
Defensive patterns
Strategy: try-catch
Validate before calling
// Client-side: proactively refresh before assuming the session is valid
const { data: { session } } = await supabase.auth.getSession()
if (!session?.user) {
// force re-login instead of sending a doomed request
} Type guard
const hasValidClaims = (c: unknown): c is { sub: string } =>
typeof c === 'object' && c !== null && typeof (c as any).sub === 'string' Try / catch
try {
const claims = await fetchUserClaims(req)
} catch (e) {
if (e instanceof Error && e.message === 'The user does not exist') {
// prompt re-auth; the account is unknown or the token is stale
return res.status(401).json({ error: { message: 'Re-authentication required' } })
}
throw e
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of supabase/supabase@beee91b9c2 (2026-08-12).
Data as JSON: /api/errors/723ec03cd810d8e9.
Report an issue: GitHub.