BerriAI/litellm · error · GetAccessTokenError
Token exchange response missing fields: {data}
Error message
Token exchange response missing fields: {data} What it means
Raised as `GetAccessTokenError` (status 400) when the token-exchange response is HTTP 200 but missing any of `access_token`, `refresh_token`, or `id_token`. Indicates OpenAI's token endpoint returned an unexpected payload shape (e.g. an error body with 200, or an API change).
Source
Thrown at litellm/llms/chatgpt/authenticator.py:278
CHATGPT_OAUTH_TOKEN_URL,
headers={"Content-Type": "application/x-www-form-urlencoded"},
content=body,
)
resp.raise_for_status()
data: Final = resp.json()
except httpx.HTTPStatusError as exc:
raise GetAccessTokenError(
message=f"Token exchange failed: {exc}",
status_code=exc.response.status_code,
)
except Exception as exc:
raise GetAccessTokenError(
message=f"Token exchange failed: {exc}",
status_code=400,
)
if not all(key in data for key in ("access_token", "refresh_token", "id_token")):
raise GetAccessTokenError(
message=f"Token exchange response missing fields: {data}",
status_code=400,
)
return {
"access_token": data["access_token"],
"refresh_token": data["refresh_token"],
"id_token": data["id_token"],
}
def _refresh_tokens(self, refresh_token: str) -> dict[str, str]:
try:
client: Final = _get_httpx_client()
resp: Final = client.post(
CHATGPT_OAUTH_TOKEN_URL,
json={
"client_id": CHATGPT_CLIENT_ID,
"grant_type": "refresh_token",
"refresh_token": refresh_token,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Read the embedded response body in the message — it usually contains an `error` field explaining the omission.
- Upgrade litellm to pick up parsing fixes for the current API contract.
- Retry the login from scratch; transient incomplete responses do occur.
- If the body shows a consent/scope error, complete the flow in a browser profile with the right account permissions.
Defensive patterns
Strategy: try-catch
Try / catch
try:
tokens = authenticator._exchange_code_for_tokens(code_data)
except GetAccessTokenError as e:
if "missing fields" in str(e):
log.error("token endpoint returned: %s", e.message) # contains raw body
raise Prevention
- Upgrade litellm when OpenAI auth payloads change.
- Inspect the embedded body for an `error` field to distinguish consent/scope problems.
- Re-login from scratch after any partial exchange failure.
When it happens
Trigger: Completing device login where the token endpoint returns 200 with a partial or error-shaped JSON (missing the three required keys); the full raw body is embedded in the message for diagnosis.
Common situations: litellm lagging behind an OpenAI auth API change; scopes/consent changes causing the server to omit tokens; proxy interference rewriting the response.
Related errors
- Device code response missing fields: {data}
- Token exchange failed: {exc}
- Refresh response missing fields: {data}
- Failed to request device code: {exc}
- Polling failed: {exc}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/64194c308214574d.
Report an issue: GitHub.