eyaltoledano/claude-task-master · error · AuthenticationError
SESSION_SET_FAILED
SESSION_SET_FAILED
Error message
Failed to set session: ${error.message} What it means
In SupabaseClient.setSession(), when `client.auth.setSession({access_token, refresh_token})` returns an error from Supabase, it is wrapped as AuthenticationError with code SESSION_SET_FAILED. This means Supabase rejected the token pair being installed as the current session — typically because the refresh token is invalid, expired, or already used.
Source
Thrown at packages/tm-core/src/modules/integration/clients/supabase-client.ts:353
} catch (error) {
this.logger.error('Error during sign out:', error);
}
}
/**
* Set session from external auth (e.g., from server callback)
*/
async setSession(session: Session): Promise<void> {
const client = this.getClient();
try {
const { error } = await client.auth.setSession({
access_token: session.access_token,
refresh_token: session.refresh_token
});
if (error) {
throw new AuthenticationError(
`Failed to set session: ${error.message}`,
'SESSION_SET_FAILED'
);
}
this.logger.info('Session set successfully');
} catch (error) {
if (error instanceof AuthenticationError) {
throw error;
}
throw new AuthenticationError(
`Failed to set session: ${(error as Error).message}`,
'SESSION_SET_FAILED'
);
}
}
View on GitHub (pinned to c0c98d367c)
Solutions
- Verify the tokens came from the same Supabase project configured in the client (URL and anon key match).
- Check the refresh token is still valid and unused — with rotating refresh tokens, only the latest token works; re-authenticate if it was already consumed.
- Ensure the session object passed in is complete (access_token and refresh_token both present and unmodified).
- Read error.message in the thrown error for the Supabase code and act on it (e.g. refresh_token_not_found → new login).
Example fix
// before
await client.setSession(oldCapturedSession);
// after
if (!oldCapturedSession?.access_token || !oldCapturedSession?.refresh_token) {
throw new Error('Incomplete session; run login again');
}
try {
await client.setSession(oldCapturedSession);
} catch (e) {
// fall back to fresh login
} Defensive patterns
Strategy: validation
Validate before calling
function canSetSession(s: unknown): s is Session {
const x = s as Partial<Session> | null;
return !!x && typeof x.access_token === 'string' && x.access_token.length > 0 &&
typeof x.refresh_token === 'string' && x.refresh_token.length > 0;
}
if (!canSetSession(incomingSession)) throw new Error('Incomplete session tokens');
await client.setSession(incomingSession); Type guard
function isSession(s: unknown): s is Session {
const x = s as Record<string, unknown> | null;
return !!x && typeof x.access_token === 'string' && typeof x.refresh_token === 'string';
} Try / catch
try {
await client.setSession(session);
} catch (e) {
if (e instanceof AuthenticationError && e.code === 'SESSION_SET_FAILED') {
// tokens rejected: clear state and force fresh login
await client.signOut();
} else throw e;
} Prevention
- Only pass sessions issued by the same Supabase project the client is configured for.
- Never reuse refresh tokens after they may have been rotated (single-use tokens).
- Validate token fields exist and are strings before calling setSession.
- Keep SUPABASE_URL/anon key aligned with the environment that minted the tokens.
When it happens
Trigger: Calling setSession(session) with a Session whose access_token/refresh_token Supabase refuses: refresh_token_not_found, invalid refresh token, or a token from a different project/instance.
Common situations: Passing a session captured from another environment (staging vs prod project); reusing a refresh token after Supabase rotated/invalidated it (single-use refresh tokens enabled); server callback handing over a truncated or stale session; SUPABASE_URL/KEY pointing to a different project than the one that issued the tokens.
Related errors
- REFRESH_FAILED
- REFRESH_FAILED
- No refresh token received from server - session refresh will
- Legacy auth.json found but no valid Supabase session.
- NOT_AUTHENTICATED
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/4664a4688f632a57.
Report an issue: GitHub.