mastra-ai/mastra · error
Failed to refresh OpenAI Codex token
Error message
Failed to refresh OpenAI Codex token
What it means
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.
Source
Thrown at mastracode/sdk/src/auth/providers/openai-codex.ts:726
createAuthorizationFlow,
decodeJwt,
extractAccountIdFromClaims,
getAccountId,
loginOpenAICodexDevice,
requireAccountId,
startLocalOAuthServer,
};
/**
* Refresh OpenAI Codex OAuth token
*/
export async function refreshOpenAICodexToken(
refreshToken: string,
previousAccountId?: string,
): Promise<OAuthCredentials> {
const result = await refreshAccessToken(refreshToken);
if (result.type !== 'success') {
throw new Error('Failed to refresh OpenAI Codex token');
}
const accountId = requireAccountId(result, previousAccountId);
return {
access: result.access,
refresh: result.refresh,
expires: result.expires,
accountId,
};
}
export const openaiCodexOAuthProvider: OAuthProviderInterface = {
id: 'openai-codex',
name: 'ChatGPT Plus/Pro (Codex Subscription)',
usesCallbackServer: true,
authModes: OPENAI_CODEX_AUTH_MODES,
View on GitHub (pinned to 75dd419e61)
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.
Example fix
// before
try {
creds = await refreshOpenAICodexToken(storedRefresh);
} catch {}
// after
try {
creds = await refreshOpenAICodexToken(storedRefresh);
} catch {
creds = await loginOpenAICodex(); // full re-auth on refresh failure
} Defensive patterns
Strategy: fallback
Validate before calling
// before refreshing: only attempt if a refresh token exists and is non-empty
if (typeof stored?.refresh !== 'string' || stored.refresh.length === 0) {
await loginOpenAICodex(); // refresh impossible; go straight to login
} Type guard
function hasRefreshToken(c: unknown): c is { refresh: string } {
return typeof c === 'object' && c !== null && typeof (c as any).refresh === 'string' && (c as any).refresh.length > 0;
} Try / catch
let creds;
try {
creds = await refreshOpenAICodexToken(stored.refresh);
} catch {
creds = await loginOpenAICodex(); // fall back to full re-auth
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
Related errors
- Anthropic token refresh failed: ${error}
- Token exchange failed
- xAI token refresh failed: ${response.status}${text ? ` ${tex
- Failed to refresh the GitHub Copilot token.
- No Copilot bearer token
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/28461edef55c0c05.
Report an issue: GitHub.