{"record":{"id":"8e50fd6575de3dbf","repo":"mastra-ai/mastra","slug":"openai-codex-device-authorization-response-missing","errorCode":null,"errorMessage":"OpenAI Codex device authorization response missing required fields","messagePattern":"OpenAI Codex device authorization response missing required fields","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/auth/providers/openai-codex.ts","lineNumber":438,"sourceCode":"    body: JSON.stringify({ client_id: CLIENT_ID, originator: 'mastracode' }),\n    signal: options?.signal,\n  });\n\n  if (!response.ok) {\n    throw new Error(`Failed to initiate OpenAI Codex device authorization: ${response.status}`);\n  }\n\n  const deviceData = (await response.json()) as {\n    device_auth_id?: string;\n    user_code?: string;\n    usercode?: string;\n    interval?: string | number;\n  };\n\n  const userCode = deviceData.user_code ?? deviceData.usercode;\n\n  if (!deviceData.device_auth_id || !userCode) {\n    throw new Error('OpenAI Codex device authorization response missing required fields');\n  }\n\n  const intervalSeconds =\n    typeof deviceData.interval === 'number' ? deviceData.interval : Number.parseInt(deviceData.interval ?? '', 10) || 5;\n\n  return {\n    deviceAuthId: deviceData.device_auth_id,\n    userCode,\n    url: DEVICE_AUTHORIZE_URL,\n    instructions: `Enter code: ${userCode}`,\n    intervalMs: Math.max(intervalSeconds, 1) * 1000,\n    deadlineAt: Date.now() + DEVICE_AUTH_TIMEOUT_MS,\n  };\n}\n\n/**\n * Perform exactly one upstream poll for a pending Codex device login.\n * The Codex device endpoint signals \"still pending\" via HTTP 403/404 (it is","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/auth/providers/openai-codex.ts#L420-L456","documentation":"The device-authorization endpoint returned HTTP 200 but the JSON payload lacks the required fields: device_auth_id and a user code (user_code or usercode). The library validates the response shape before starting the polling loop, since polling would be meaningless without these identifiers. This is a defensive schema check against API contract changes or unexpected responses.","triggerScenarios":"The device-auth endpoint responding with an unexpected JSON body — e.g. an error object with 200 status, a changed field name (OpenAI API contract change), a captive-portal/interstitial HTML parsed oddly, or an outdated CLIENT_ID receiving a different response schema.","commonSituations":"OpenAI changing/renaming device-auth response fields; an SDK version too old for the current API; proxy/VPN returning a login page with status 200; regional blocks returning a non-standard payload.","solutions":["Update the mastracode SDK to the latest version so the response schema matches the current OpenAI API.","Log/inspect the raw response body (temporarily) to confirm what the endpoint actually returned.","Check for proxies/VPNs or captive portals that might replace the response with an HTML page.","Retry later if OpenAI is mid-API-migration; report a bug with the raw payload if the SDK is current."],"exampleFix":"// before: assuming fields exist\nconst { device_auth_id, user_code } = await response.json();\n\n// after: validate defensively\nconst data = await response.json();\nif (!data?.device_auth_id || !(data.user_code ?? data.usercode)) {\n  throw new Error('Unexpected device-auth response: ' + JSON.stringify(data));\n}","handlingStrategy":"validation","validationCode":"function isValidDeviceAuthResponse(d: unknown): d is { device_auth_id: string; user_code?: string; usercode?: string } {\n  const o = d as any;\n  return !!o && typeof o.device_auth_id === 'string' && (typeof o.user_code === 'string' || typeof o.usercode === 'string');\n}","typeGuard":"function isDeviceAuthData(d: unknown): d is { device_auth_id: string; user_code?: string; usercode?: string; interval?: string | number } {\n  const o = d as Record<string, unknown>;\n  return typeof o?.device_auth_id === 'string' &&\n    (typeof o?.user_code === 'string' || typeof o?.usercode === 'string');\n}","tryCatchPattern":"try {\n  const creds = await loginOpenAICodexDevice({});\n} catch (e) {\n  if (e.message.includes('missing required fields')) {\n    console.error('OpenAI device-auth contract changed — update SDK, payload:', e);\n  } else throw e;\n}","preventionTips":["Pin and regularly update the SDK against OpenAI API changes.","Log raw device-auth responses when debugging.","Disable interfering proxies/VPNs during login.","Alert on this error in CI to catch API drift early."],"tags":["oauth","schema-validation","device-login","api-contract"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}