{"record":{"id":"ca58a2ba1737a14c","repo":"mastra-ai/mastra","slug":"xai-token-response-missing-access-token","errorCode":null,"errorMessage":"xAI token response missing access_token","messagePattern":"xAI token response missing access_token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/auth/providers/xai.ts","lineNumber":54,"sourceCode":"/** The verification URI is opened by the user; only accept https URLs. */\nfunction validateVerificationUri(raw: string): string {\n  let parsed: URL;\n  try {\n    parsed = new URL(raw);\n  } catch {\n    throw new Error(`xAI device authorization returned an invalid verification_uri: ${raw}`);\n  }\n  if (parsed.protocol !== 'https:') {\n    throw new Error(`xAI device authorization returned a non-https verification_uri: ${raw}`);\n  }\n  return parsed.toString();\n}\n\nfunction credentialsFromTokenResponse(data: unknown, previousRefreshToken?: string): OAuthCredentials {\n  const record = (data ?? {}) as Record<string, unknown>;\n  const access = record.access_token;\n  if (typeof access !== 'string' || access.length === 0) {\n    throw new Error('xAI token response missing access_token');\n  }\n\n  // xAI may not rotate the refresh token on refresh; keep the previous one.\n  const refresh =\n    typeof record.refresh_token === 'string' && record.refresh_token.length > 0\n      ? record.refresh_token\n      : previousRefreshToken;\n  if (!refresh) {\n    throw new Error('xAI token response missing refresh_token');\n  }\n\n  const expiresIn =\n    typeof record.expires_in === 'number' && record.expires_in > 0\n      ? record.expires_in\n      : DEFAULT_TOKEN_EXPIRES_IN_SECONDS;\n\n  return {\n    access,","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/auth/providers/xai.ts#L36-L72","documentation":"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.","triggerScenarios":"pollXAITokenOnce (during device-flow polling) or refreshXAIToken receives a JSON body where record.access_token is missing, null, or not a non-empty string.","commonSituations":"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.","solutions":["Log the raw response body to see what the token endpoint actually returned.","For device-flow polling, ensure the user completed authorization before the request that failed (handle authorization_pending/slow_down states).","Verify no proxy is altering the response and that the xAI token endpoint URL is correct.","Retry the flow; if the provider contract changed, upgrade the SDK."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// pre-check a raw token body before handing it to any consumer\nfunction looksLikeTokenBody(b: unknown): boolean {\n  const r = (b ?? {}) as Record<string, unknown>;\n  return typeof r.access_token === 'string' && r.access_token.length > 0;\n}","typeGuard":"function hasAccessToken(data: unknown): data is { access_token: string } {\n  const r = (data ?? {}) as Record<string, unknown>;\n  return typeof r.access_token === 'string' && r.access_token.length > 0;\n}","tryCatchPattern":"try {\n  await sdk.auth.login('xai', callbacks);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('missing access_token')) {\n    // response body was not a valid token grant; inspect/retry the flow\n    restartDeviceFlowIfPending();\n  }\n}","preventionTips":["Handle device-flow pending states (authorization_pending/slow_down) before expecting tokens","Log raw token responses when debugging so malformed bodies are visible","Ensure the token endpoint URL is exact and not proxied/rewritten","Upgrade the SDK if the provider's response contract changes"],"tags":["oauth","xai","response-validation"],"backgroundTag":"missing-access-token","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}