{"record":{"id":"5749880d52f71440","repo":"eyaltoledano/claude-task-master","slug":"auth-timeout","errorCode":"AUTH_TIMEOUT","errorMessage":"'Authentication flow expired'","messagePattern":"'Authentication flow expired'","errorType":"exception","errorClass":"AuthenticationError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/auth/services/oauth-service.ts","lineNumber":397,"sourceCode":"\t\t\t\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\t\t\t\tuserId: tokens.user_id,\n\t\t\t\t\t\t\temail: tokens.email,\n\t\t\t\t\t\t\texpiresAt: tokens.expires_in\n\t\t\t\t\t\t\t\t? new Date(Date.now() + tokens.expires_in * 1000).toISOString()\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\ttokenType: 'standard',\n\t\t\t\t\t\t\tsavedAt: new Date().toISOString()\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tcase 'failed':\n\t\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t\tdata.error_description || data.error || 'Authentication failed',\n\t\t\t\t\t\t\t'OAUTH_FAILED'\n\t\t\t\t\t\t);\n\n\t\t\t\t\tcase 'expired':\n\t\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t\t'Authentication flow expired',\n\t\t\t\t\t\t\t'AUTH_TIMEOUT'\n\t\t\t\t\t\t);\n\n\t\t\t\t\tcase 'pending':\n\t\t\t\t\tcase 'authenticating':\n\t\t\t\t\t\t// Still waiting, continue polling\n\t\t\t\t\t\tthis.logger.debug(\n\t\t\t\t\t\t\t`Flow status: ${data.status}, continuing to poll`\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.logger.warn(`Unknown flow status: ${data.status}`);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof AuthenticationError) {\n\t\t\t\t\tthrow error;","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/auth/services/oauth-service.ts#L379-L415","documentation":"AUTH_TIMEOUT is thrown when the backend reports the flow status as 'expired' — the OAuth flow exceeded the server-side lifetime before the user finished authenticating in the browser. Unlike the client-side timeout (same code, thrown at the end of the loop), this is the server explicitly expiring the flow.","triggerScenarios":"During `credentials()`, polling returns `{success:true,status:'expired'}` — the user took longer than the server's flow TTL (typically a few minutes) to complete the browser login, or never opened/completed it before expiry.","commonSituations":"User leaves the browser tab open but doesn't finish login; login tab closed and rediscovered after the flow expired; slow corporate SSO/multi-factor prompts exceeding the flow window; polling started long after the auth URL was generated.","solutions":["Call `credentials()` again immediately to start a fresh flow and complete the browser login promptly.","Start the browser login as soon as the URL is produced; don't let the auth URL sit idle.","If MFA/SSO prompts routinely take too long, ask the admin to extend the server-side flow TTL (client `timeout` option only affects local polling).","Automate the retry: catch AUTH_TIMEOUT and re-initiate the flow once with a user prompt to finish login faster."],"exampleFix":"// before: single attempt, expires if user is slow\nconst creds = await oauthService.credentials();\n// after: retry once on server-side expiry\ntry {\n  const creds = await oauthService.credentials();\n} catch (e) {\n  if (e instanceof AuthenticationError && e.code === 'AUTH_TIMEOUT') {\n    console.error('Login expired, starting a new flow — complete it promptly.');\n    return oauthService.credentials();\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isAuthTimeout(e: unknown): e is AuthenticationError {\n  return e instanceof AuthenticationError && e.code === 'AUTH_TIMEOUT';\n}","tryCatchPattern":"try {\n  const creds = await oauthService.credentials();\n} catch (e) {\n  if (e instanceof AuthenticationError && e.code === 'AUTH_TIMEOUT') {\n    console.error('Login flow expired — starting a new one; complete the browser step promptly.');\n    return oauthService.credentials();\n  }\n  throw e;\n}","preventionTips":["Complete the browser login immediately after the auth window opens.","Don't start the flow and walk away — server-side TTL is only a few minutes.","For slow MFA/SSO, ask the admin to extend the server flow lifetime.","Catch AUTH_TIMEOUT and automatically restart the flow once."],"tags":["oauth","timeout","expired-flow","authentication"],"backgroundTag":"oauth-flow-expired","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}