BerriAI/litellm · error · GetAccessTokenError
Polling failed: {exc}
Error message
Polling failed: {exc} What it means
Raised as `GetAccessTokenError` when polling the ChatGPT device-authorization token endpoint returns an HTTP error other than 403/404 (those are treated as "keep waiting" and retried). This occurs during the second phase of device login, after the user has been shown a code.
Source
Thrown at litellm/llms/chatgpt/authenticator.py:232
if all(
key in data
for key in (
"authorization_code",
"code_challenge",
"code_verifier",
)
):
return data
if resp.status_code in (403, 404):
time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))
continue
resp.raise_for_status()
except httpx.HTTPStatusError as exc:
status_code = exc.response.status_code if exc.response else None
if status_code in (403, 404):
time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))
continue
raise GetAccessTokenError(
message=f"Polling failed: {exc}",
status_code=exc.response.status_code,
)
except Exception as exc:
raise GetAccessTokenError(
message=f"Polling failed: {exc}",
status_code=400,
)
time.sleep(max(interval, DEVICE_CODE_POLL_SLEEP_SECONDS))
raise GetAccessTokenError(
message="Timed out waiting for device authorization",
status_code=408,
)
def _exchange_code_for_tokens(self, code_data: dict[str, str]) -> dict[str, str]:
try:
client: Final = _get_httpx_client()View on GitHub (pinned to 6c2dcb801b)
Solutions
- Restart the login flow and complete the browser approval promptly after the user code is displayed.
- Read the embedded HTTP status/message — 400 with `invalid_grant`/expired means you must start a fresh device-code request, not retry the poll.
- If it is a 5xx, retry the whole flow after a minute.
- Upgrade litellm in case polling semantics changed.
Defensive patterns
Strategy: try-catch
Try / catch
try:
tokens = authenticator.get_access_token()
except GetAccessTokenError as e:
if e.status_code == 400: # expired/invalid device code: restart flow, don't retry poll
device = authenticator._request_device_code()
tokens = authenticator.get_access_token()
else:
raise Prevention
- Complete browser approval immediately after the user code appears.
- Treat 400 during polling as flow-expired: restart from device-code request.
- Retry only 5xx statuses; 4xx poll errors are terminal.
When it happens
Trigger: While waiting for the user to approve the device code at OpenAI's verification page, the token poll returns e.g. 400 (`invalid_grant`, expired device code), 401, or 5xx. The user never finishing authorization before the code expires typically produces a terminal 400.
Common situations: User starts `litellm` ChatGPT login but does not complete browser approval within the code's validity window; the auth server invalidates the session; too-slow or hung polling behind flaky networks.
Related errors
- Failed to request device code: {exc}
- Timed out waiting for device authorization
- Device code response missing fields: {data}
- Token exchange failed: {exc}
- Refresh token failed: {exc}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/4debe053960bba9e.
Report an issue: GitHub.