eyaltoledano/claude-task-master · error · AuthenticationError
MFA_VERIFICATION_FAILED
MFA_VERIFICATION_FAILED
Error message
`MFA verification failed: ${(error as Error).message}` What it means
This error is thrown by SessionManager.verifyMFA when the MFA verification flow fails with an unexpected error. If the underlying failure is already an AuthenticationError it is re-thrown as-is; otherwise it is wrapped in a new AuthenticationError with code MFA_VERIFICATION_FAILED. It signals that multi-factor authentication could not be completed during login.
Source
Thrown at packages/tm-core/src/modules/auth/services/session-manager.ts:356
token: session.access_token,
refreshToken: session.refresh_token,
userId: user.id,
email: user.email,
expiresAt: session.expires_at
? new Date(session.expires_at * 1000).toISOString()
: undefined,
tokenType: 'standard',
savedAt: new Date().toISOString(),
selectedContext: context || undefined
};
this.logger.info('Successfully verified MFA and authenticated');
return credentials;
} catch (error) {
if (error instanceof AuthenticationError) {
throw error;
}
throw new AuthenticationError(
`MFA verification failed: ${(error as Error).message}`,
'MFA_VERIFICATION_FAILED'
);
}
}
// ========== Session Lifecycle ==========
/**
* Logout and clear credentials
*/
async logout(): Promise<void> {
await this.waitForInitialization();
try {
// First try to sign out from Supabase to revoke tokens
await this.supabaseClient.signOut();
} catch (error) {
// Log but don't throw - we still want to clear local credentialsView on GitHub (pinned to c0c98d367c)
Solutions
- Re-request a fresh MFA code and verify it promptly before it expires
- Check network connectivity and Supabase service status, then retry
- Confirm the authenticator app time sync (TOTP drift) and re-enroll MFA if codes consistently fail
- Inspect the wrapped cause message to identify the underlying provider error
Example fix
// before
await sessionManager.verifyMFA('123456');
// after
try {
await sessionManager.verifyMFA(await promptFreshTotpCode());
} catch (e) {
if (e instanceof AuthenticationError && e.code === 'MFA_VERIFICATION_FAILED') {
await sessionManager.requestMfaChallenge(); // get a new code, then retry
} else { throw e; }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before verifying, ensure a code was entered and a challenge is active
if (!code || !/^\d{6}$/.test(code.trim())) throw new Error('Enter the 6-digit MFA code');
if (!sessionManager.hasPendingChallenge()) await sessionManager.requestMfaChallenge(); Type guard
function isAuthenticationError(e: unknown): e is AuthenticationError {
return e instanceof AuthenticationError;
} Try / catch
try {
await sessionManager.verifyMFA(code);
} catch (e) {
if (isAuthenticationError(e) && e.code === 'MFA_VERIFICATION_FAILED') {
// prompt for a fresh code / check connectivity, then retry once
} else { throw e; }
} Prevention
- Always request a fresh challenge before prompting for a code; never reuse old codes
- Sync device clock (TOTP drift) when codes consistently fail
- Distinguish AuthenticationError from other errors so network issues get a retry, not a re-prompt
- Limit retry attempts to avoid account lockout
When it happens
Trigger: Calling verifyMFA (directly or via the credentials/session flows) when the MFA code is wrong/expired, the Supabase challenge verify call throws, or any non-AuthenticationError (network, malformed response) escapes the try block.
Common situations: User types an outdated 6-digit code after requesting a new one; authenticator app clock drift causing TOTP mismatch; network outage or Supabase outage mid-login; Supabase client returning an error object that is not an AuthenticationError.
Related errors
- MFA_REQUIRED
- MFA_VERIFICATION_FAILED
- INVALID_MFA_CODE
- MFA_VERIFICATION_FAILED
- Invalid maxAttempts value: ${maxAttempts}. Must be a positiv
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/80f2de2a47288d93.
Report an issue: GitHub.