mastra-ai/mastra · error

xAI token response missing access_token

Error message

xAI token response missing access_token

What it means

credentialsFromTokenResponse validates the xAI token endpoint response shape before constructing OAuthCredentials. If access_token is absent, empty, or not a string, the response is considered invalid and this error is thrown instead of storing broken credentials.

Solutions

  1. Log the raw response body to see what the token endpoint actually returned.
  2. For device-flow polling, ensure the user completed authorization before the request that failed (handle authorization_pending/slow_down states).
  3. Verify no proxy is altering the response and that the xAI token endpoint URL is correct.
  4. Retry the flow; if the provider contract changed, upgrade the SDK.
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-check a raw token body before handing it to any consumer
function looksLikeTokenBody(b: unknown): boolean {
  const r = (b ?? {}) as Record<string, unknown>;
  return typeof r.access_token === 'string' && r.access_token.length > 0;
}

Type guard

function hasAccessToken(data: unknown): data is { access_token: string } {
  const r = (data ?? {}) as Record<string, unknown>;
  return typeof r.access_token === 'string' && r.access_token.length > 0;
}

Try / catch

try {
  await sdk.auth.login('xai', callbacks);
} catch (e) {
  if (e instanceof Error && e.message.includes('missing access_token')) {
    // response body was not a valid token grant; inspect/retry the flow
    restartDeviceFlowIfPending();
  }
}

Prevention

When it happens

Trigger: pollXAITokenOnce (during device-flow polling) or refreshXAIToken receives a JSON body where record.access_token is missing, null, or not a non-empty string.

Common situations: The token endpoint returned an error JSON (e.g. authorization_pending rendered as 200 or an error body without tokens); API contract change; proxy returning HTML that fails JSON parsing upstream or a partial body.

Related errors


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

Appendix: source

Thrown at mastracode/sdk/src/auth/providers/xai.ts:54

/** The verification URI is opened by the user; only accept https URLs. */
function validateVerificationUri(raw: string): string {
  let parsed: URL;
  try {
    parsed = new URL(raw);
  } catch {
    throw new Error(`xAI device authorization returned an invalid verification_uri: ${raw}`);
  }
  if (parsed.protocol !== 'https:') {
    throw new Error(`xAI device authorization returned a non-https verification_uri: ${raw}`);
  }
  return parsed.toString();
}

function credentialsFromTokenResponse(data: unknown, previousRefreshToken?: string): OAuthCredentials {
  const record = (data ?? {}) as Record<string, unknown>;
  const access = record.access_token;
  if (typeof access !== 'string' || access.length === 0) {
    throw new Error('xAI token response missing access_token');
  }

  // xAI may not rotate the refresh token on refresh; keep the previous one.
  const refresh =
    typeof record.refresh_token === 'string' && record.refresh_token.length > 0
      ? record.refresh_token
      : previousRefreshToken;
  if (!refresh) {
    throw new Error('xAI token response missing refresh_token');
  }

  const expiresIn =
    typeof record.expires_in === 'number' && record.expires_in > 0
      ? record.expires_in
      : DEFAULT_TOKEN_EXPIRES_IN_SECONDS;

  return {
    access,

View on GitHub (pinned to 75dd419e61)