mastra-ai/mastra · error

Failed to extract ChatGPT account id from OpenAI Codex token

Error message

Failed to extract ChatGPT account id from OpenAI Codex token

What it means

OpenAI Codex tokens carry the ChatGPT account id inside the JWT (id_token/access token claims). requireAccountId extracts it via getAccountId, allowing an explicit fallback, and throws if neither the token claims nor the fallback yield an account id — because downstream Codex API calls require the ChatGPT account id header/claim.

Source

Thrown at mastracode/sdk/src/auth/providers/openai-codex.ts:138

  if (!payload) return null;
  const accountId = payload.chatgpt_account_id ?? payload[JWT_CLAIM_PATH]?.chatgpt_account_id;
  return typeof accountId === 'string' && accountId.length > 0 ? accountId : null;
}

function getAccountId(tokens: { idToken?: string; access: string }, fallback?: string): string | undefined {
  const fromIdToken = tokens.idToken ? extractAccountIdFromClaims(decodeJwt(tokens.idToken)) : null;
  if (fromIdToken) return fromIdToken;

  const fromAccessToken = extractAccountIdFromClaims(decodeJwt(tokens.access));
  if (fromAccessToken) return fromAccessToken;

  return fallback;
}

function requireAccountId(tokens: { idToken?: string; access: string }, fallback?: string): string {
  const accountId = getAccountId(tokens, fallback);
  if (!accountId) {
    throw new Error('Failed to extract ChatGPT account id from OpenAI Codex token');
  }
  return accountId;
}

type TokenResponseJson = {
  id_token?: string;
  access_token?: string;
  refresh_token?: string;
  expires_in?: number;
};

function tokenResponseToResult(json: TokenResponseJson, logPrefix: string): TokenResult {
  if (!json.access_token || !json.refresh_token) {
    console.error(`[openai-codex] ${logPrefix} response missing fields:`, json);
    return { type: 'failed' };
  }

  return {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Re-run the Codex device login to obtain fresh tokens that include the account id claim
  2. Supply the account id explicitly via the fallback parameter if you know it
  3. Inspect the token: decode the JWT payload (middle segment) and check for the account id claim to confirm the cause
  4. Check for an OpenAI token-format change and update the SDK

Example fix

// before
const id = requireAccountId(tokens); // throws when claim missing
// after
const id = requireAccountId(tokens, process.env.CHATGPT_ACCOUNT_ID); // explicit fallback
Defensive patterns

Strategy: fallback

Validate before calling

// Decode the JWT payload and check for the account id claim before calling
def decodeJwtPayload(token) {
  const part = token?.split('.')[1];
  if (!part) return null;
  try { return JSON.parse(Buffer.from(part, 'base64url').toString('utf8')); } catch { return null;
  }
}
const claims = decodeJwtPayload(tokens.idToken ?? tokens.access);
const accountId = claims?.chatgpt_account_id ?? fallback;

Type guard

function hasAccountIdClaim(tokens: { idToken?: string; access: string }): boolean {
  const payload = decodeJwtPayloadSafe(tokens.idToken ?? tokens.access);
  return typeof payload?.['chatgpt_account_id'] === 'string' && !!payload['chatgpt_account_id'];
}

Try / catch

try {
  const accountId = provider.accountId();
} catch (err) {
  if (err instanceof Error && err.message.includes('Failed to extract ChatGPT account id')) {
    await login('openai-codex'); // mint fresh tokens that include the claim
  } else throw err;
}

Prevention

When it happens

Trigger: Calling accountId or completing pollCodexDeviceLogin with tokens whose id_token/access JWT lacks the expected chatgpt_account_id / account id claim, no fallback supplied, or a token that failed to decode (malformed/truncated JWT).

Common situations: Logging in with an API-key-only or non-ChatGPT account whose token lacks the claim; corrupted or hand-truncated stored tokens; OpenAI changing the JWT claim structure; passing tokens obtained outside this library.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/35017fab3bcba40d. Report an issue: GitHub.