{"record":{"id":"7c301813529fcc5c","repo":"BerriAI/litellm","slug":"device-code-response-missing-fields-data","errorCode":null,"errorMessage":"Device code response missing fields: {data}","messagePattern":"Device code response missing fields: (.+?)","errorType":"exception","errorClass":"GetDeviceCodeError","httpStatus":400,"severity":"error","filePath":"litellm/llms/chatgpt/authenticator.py","lineNumber":189,"sourceCode":"            )\n            resp.raise_for_status()\n            data: Final = resp.json()\n        except httpx.HTTPStatusError as exc:\n            raise GetDeviceCodeError(\n                message=f\"Failed to request device code: {exc}\",\n                status_code=exc.response.status_code,\n            )\n        except Exception as exc:\n            raise GetDeviceCodeError(\n                message=f\"Failed to request device code: {exc}\",\n                status_code=400,\n            )\n\n        device_auth_id: Final = data.get(\"device_auth_id\")\n        user_code: Final = data.get(\"user_code\") or data.get(\"usercode\")\n        interval: Final = data.get(\"interval\")\n        if not device_auth_id or not user_code:\n            raise GetDeviceCodeError(\n                message=f\"Device code response missing fields: {data}\",\n                status_code=400,\n            )\n        return {\n            \"device_auth_id\": device_auth_id,\n            \"user_code\": user_code,\n            \"interval\": str(interval or \"5\"),\n        }\n\n    def _poll_for_authorization_code(self, device_code: dict[str, str]) -> dict[str, str]:\n        client: Final = _get_httpx_client()\n        interval: Final = int(device_code.get(\"interval\", \"5\"))\n        start_time: Final = time.time()\n        while time.time() - start_time < DEVICE_CODE_TIMEOUT_SECONDS:\n            try:\n                resp = client.post(\n                    CHATGPT_DEVICE_TOKEN_URL,\n                    json={","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/chatgpt/authenticator.py#L171-L207","documentation":"Raised as `GetDeviceCodeError` (status 400) when the device-code endpoint returns HTTP 200 but the JSON body lacks `device_auth_id` or `user_code` (the code also accepts `usercode` as an alias). This means OpenAI's auth API changed shape or returned an unexpected payload.","triggerScenarios":"Calling `get_access_token()` on the ChatGPT authenticator when the device-code response omits required fields — typically after an API contract change on OpenAI's side, or when a proxy/interceptor returns 200 with an HTML or differently-shaped JSON body.","commonSituations":"litellm version out of date relative to OpenAI's auth API changes; transparent proxies that respond 200 with a block page; rare server-side bugs returning incomplete payloads.","solutions":["Upgrade litellm to the latest release — the parsing code is updated when OpenAI changes the contract.","Inspect the raw response by enabling debug logging or curling the device-code URL manually to see what body comes back.","If a proxy is returning a block page, bypass it or allowlist OpenAI auth domains.","Report the issue to the litellm repo with the (redacted) response body if the API changed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    device = authenticator._request_device_code()\nexcept GetDeviceCodeError as e:\n    if \"missing fields\" in str(e):\n        # API contract drift or proxy block page: inspect body, upgrade litellm\n        log.error(\"unexpected device-code payload: %s\", e.message)\n    raise","preventionTips":["Stay on a recent litellm release.","Diff the raw device-code response body when this fires to identify proxy interference.","Allowlist OpenAI auth domains on intercepting proxies."],"tags":["chatgpt","oauth","device-flow","api-contract"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}