{"record":{"id":"28461edef55c0c05","repo":"mastra-ai/mastra","slug":"failed-to-refresh-openai-codex-token","errorCode":null,"errorMessage":"Failed to refresh OpenAI Codex token","messagePattern":"Failed to refresh OpenAI Codex token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/auth/providers/openai-codex.ts","lineNumber":726,"sourceCode":"  createAuthorizationFlow,\n  decodeJwt,\n  extractAccountIdFromClaims,\n  getAccountId,\n  loginOpenAICodexDevice,\n  requireAccountId,\n  startLocalOAuthServer,\n};\n\n/**\n * Refresh OpenAI Codex OAuth token\n */\nexport async function refreshOpenAICodexToken(\n  refreshToken: string,\n  previousAccountId?: string,\n): Promise<OAuthCredentials> {\n  const result = await refreshAccessToken(refreshToken);\n  if (result.type !== 'success') {\n    throw new Error('Failed to refresh OpenAI Codex token');\n  }\n\n  const accountId = requireAccountId(result, previousAccountId);\n\n  return {\n    access: result.access,\n    refresh: result.refresh,\n    expires: result.expires,\n    accountId,\n  };\n}\n\nexport const openaiCodexOAuthProvider: OAuthProviderInterface = {\n  id: 'openai-codex',\n  name: 'ChatGPT Plus/Pro (Codex Subscription)',\n  usesCallbackServer: true,\n  authModes: OPENAI_CODEX_AUTH_MODES,\n","sourceCodeStart":708,"sourceCodeEnd":744,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/auth/providers/openai-codex.ts#L708-L744","documentation":"Thrown by refreshOpenAICodexToken when refreshAccessToken(refreshToken) returns a non-success result. The stored refresh token could not be exchanged for new credentials at the OpenAI token endpoint, so the library cannot silently renew the Codex credentials.","triggerScenarios":"Automatic or manual token refresh calls refreshOpenAICodexToken(refreshToken) and the provider responds with an OAuth error (invalid_grant, invalid_client, etc.), i.e. result.type !== 'success'.","commonSituations":"The refresh token was revoked (user logged out remotely or credentials were reset); tokens were rotated elsewhere and the stored one is stale; the OpenAI app credentials/client changed; long-unused tokens expired.","solutions":["Re-run the full Codex OAuth login to obtain fresh access and refresh tokens.","Confirm the stored refresh token belongs to the current client credentials (client id/secret unchanged).","Check the provider account for revoked sessions/API key resets and re-authorize.","Retry once after transient network failure; if invalid_grant persists, refresh token is dead."],"exampleFix":"// before\ntry {\n  creds = await refreshOpenAICodexToken(storedRefresh);\n} catch {}\n// after\ntry {\n  creds = await refreshOpenAICodexToken(storedRefresh);\n} catch {\n  creds = await loginOpenAICodex(); // full re-auth on refresh failure\n}","handlingStrategy":"fallback","validationCode":"// before refreshing: only attempt if a refresh token exists and is non-empty\nif (typeof stored?.refresh !== 'string' || stored.refresh.length === 0) {\n  await loginOpenAICodex(); // refresh impossible; go straight to login\n}","typeGuard":"function hasRefreshToken(c: unknown): c is { refresh: string } {\n  return typeof c === 'object' && c !== null && typeof (c as any).refresh === 'string' && (c as any).refresh.length > 0;\n}","tryCatchPattern":"let creds;\ntry {\n  creds = await refreshOpenAICodexToken(stored.refresh);\n} catch {\n  creds = await loginOpenAICodex(); // fall back to full re-auth\n}","preventionTips":["Treat refresh failure as 're-auth required' and wire an automatic login fallback","Keep client id/secret stable; changing them invalidates stored grants","Refresh proactively before expiry instead of waiting for failure","Persist the newest refresh token immediately after each successful refresh"],"tags":["oauth","openai","token-refresh"],"backgroundTag":"oauth-refresh-token-invalid","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}