eyaltoledano/claude-task-master · error · AuthenticationError
REFRESH_FAILED
REFRESH_FAILED
Error message
'Failed to refresh session'
What it means
AuthenticationError with code REFRESH_FAILED thrown by SessionManager.refreshToken when supabaseClient.refreshSession() resolves without a session. Supabase's auth call did not return a refreshable session, typically because the refresh token is missing, expired, or already revoked. The method exists for explicit refresh requests; Supabase normally refreshes automatically via the storage adapter.
Source
Thrown at packages/tm-core/src/modules/auth/services/session-manager.ts:180
tokenType: 'standard',
savedAt: new Date().toISOString(),
selectedContext: context || undefined
};
}
/**
* Refresh authentication token using Supabase session
* Note: Supabase handles token refresh automatically via the session storage adapter.
* This method is mainly for explicit refresh requests.
*/
async refreshToken(): Promise<AuthCredentials> {
await this.waitForInitialization();
try {
// Use Supabase's built-in session refresh
const session = await this.supabaseClient.refreshSession();
if (!session) {
throw new AuthenticationError(
'Failed to refresh session',
'REFRESH_FAILED'
);
}
// Sync user info to context store
this.contextStore.saveContext({
userId: session.user.id,
email: session.user.email
});
// Build credentials response
const context = this.contextStore.getContext();
const credentials: AuthCredentials = {
token: session.access_token,
refreshToken: session.refresh_token,
userId: session.user.id,
email: session.user.email,View on GitHub (pinned to c0c98d367c)
Solutions
- Run the full login flow (task-master auth login) to obtain a fresh session
- Clear stale stored credentials and re-authenticate
- Check system clock skew (NTP) if the token was recently issued
- Ensure no concurrent sessions are rotating the same refresh token
Example fix
// before: assuming refresh always works
const creds = await sessionManager.refreshToken();
// after: re-login on REFRESH_FAILED
try {
const creds = await sessionManager.refreshToken();
} catch (e) {
if (e instanceof AuthenticationError && e.code === 'REFRESH_FAILED') {
await sessionManager.login(); // full re-authentication
}
} Defensive patterns
Strategy: fallback
Validate before calling
// check stored session expiry before attempting refresh
const creds = await sessionManager.getCachedCredentials?.();
if (creds?.expiresAt && new Date(creds.expiresAt) < new Date()) {
await reauthenticate(); // session clearly expired
} Type guard
function isRefreshFailed(e: unknown): e is AuthenticationError {
return e instanceof AuthenticationError && e.code === 'REFRESH_FAILED';
} Try / catch
try {
await sessionManager.refreshToken();
} catch (e) {
if (isRefreshFailed(e)) {
await sessionManager.login(); // full re-auth fallback
} else throw e;
} Prevention
- Treat refresh as best-effort: always fall back to interactive re-login
- Sync machine clock (NTP) to avoid premature expiry judgments
- Avoid sharing one account/session across many machines concurrently
- Schedule re-login before long-running automation starts
When it happens
Trigger: Calling refreshToken() when there is no persisted session, the refresh token has expired (Supabase default ~ at least one reuse window passed), the token was already used/rotated elsewhere, or the user was signed out server-side.
Common situations: Long-lived CLI installations where the session expired weeks ago; logging in on another machine invalidated the refresh token; clock skew on the local machine; clearing ~/.taskmaster auth storage while still calling authenticated commands.
Related errors
- REFRESH_FAILED
- SESSION_SET_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/524cf5dc94140d5e.
Report an issue: GitHub.