{"record":{"id":"4debe053960bba9e","repo":"BerriAI/litellm","slug":"polling-failed-exc","errorCode":null,"errorMessage":"Polling failed: {exc}","messagePattern":"Polling failed: (.+?)","errorType":"exception","errorClass":"GetAccessTokenError","httpStatus":null,"severity":"error","filePath":"litellm/llms/chatgpt/authenticator.py","lineNumber":232,"sourceCode":"                    if all(\n                        key in data\n                        for key in (\n                            \"authorization_code\",\n                            \"code_challenge\",\n                            \"code_verifier\",\n                        )\n                    ):\n                        return data\n                if resp.status_code in (403, 404):\n                    time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))\n                    continue\n                resp.raise_for_status()\n            except httpx.HTTPStatusError as exc:\n                status_code = exc.response.status_code if exc.response else None\n                if status_code in (403, 404):\n                    time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))\n                    continue\n                raise GetAccessTokenError(\n                    message=f\"Polling failed: {exc}\",\n                    status_code=exc.response.status_code,\n                )\n            except Exception as exc:\n                raise GetAccessTokenError(\n                    message=f\"Polling failed: {exc}\",\n                    status_code=400,\n                )\n            time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))\n\n        raise GetAccessTokenError(\n            message=\"Timed out waiting for device authorization\",\n            status_code=408,\n        )\n\n    def _exchange_code_for_tokens(self, code_data: dict[str, str]) -> dict[str, str]:\n        try:\n            client: Final = _get_httpx_client()","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/chatgpt/authenticator.py#L214-L250","documentation":"GetAccessTokenError raised while polling the ChatGPT device-authorization endpoint: the poll returned an HTTPStatusError whose code is not 403/404 (those two are retried as 'keep waiting'). The message contains the underlying httpx error and the authenticator attaches the upstream status code, so you can tell a 400 (expired/invalid device code) from a 5xx (upstream incident).","triggerScenarios":"Polling CHATGPT_DEVICE_CODE_URL during device login and receiving e.g. 400 (device_auth_id expired or invalid), 401, or 500 — any non-403/404 error status aborts with this error.","commonSituations":"User took too long to approve and the device code went stale mid-poll; rate-limited polling; auth.openai.com incidents; reused device_auth_id from a previous login attempt.","solutions":["Restart the login flow to get a fresh device code and approve it promptly at the printed verify URL","If the status is 429, slow down — do not run multiple logins concurrently from the same host","Upgrade litellm if the poll endpoint contract changed","Check the status code embedded in the message to distinguish stale-code (400) from upstream failure (5xx)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from litellm.llms.chatgpt.authenticator import GetAccessTokenError\n\ntry:\n    tokens = authenticator.login()\nexcept GetAccessTokenError as e:\n    if \"Polling failed\" in str(e) and e.status_code in (400, 429):\n        # stale device code or rate limit: restart with a fresh code\n        tokens = authenticator.login()  # prompts a new device code\n    else:\n        raise","preventionTips":["Approve the device code immediately after it is printed","Run only one device login at a time per host","Treat repeated 429s as a signal to back off, not to loop faster"],"tags":["chatgpt","oauth","device-code","polling","auth"],"backgroundTag":"oauth-device-flow-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}