{"record":{"id":"08475d5e099cee90","repo":"BerriAI/litellm","slug":"oauth2-token-response-for-mcp-server-server-serv-08475d","errorCode":null,"errorMessage":"OAuth2 token response for MCP server '{server.server_id}' missing 'access_token'","messagePattern":"OAuth2 token response for MCP server '(.+?)' missing 'access_token'","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py","lineNumber":167,"sourceCode":"            response: Final = await client.post(server.token_url, data=data, headers=token_request.headers or None)\n            response.raise_for_status()\n        except httpx.HTTPStatusError as exc:\n            raise ValueError(\n                f\"OAuth2 token request for MCP server '{server.server_id}' \"\n                f\"failed with status {exc.response.status_code}\"\n            ) from exc\n\n        body: Final = response.json()\n\n        if not isinstance(body, dict):\n            raise ValueError(\n                f\"OAuth2 token response for MCP server '{server.server_id}' \"\n                f\"returned non-object JSON (got {type(body).__name__})\"\n            )\n\n        access_token: Final = body.get(\"access_token\")\n        if not access_token:\n            raise ValueError(f\"OAuth2 token response for MCP server '{server.server_id}' missing 'access_token'\")\n\n        # Safely parse expires_in — providers may return null or non-numeric values\n        raw_expires_in: Final = body.get(\"expires_in\")\n        try:\n            expires_in = int(raw_expires_in) if raw_expires_in is not None else MCP_OAUTH2_TOKEN_CACHE_DEFAULT_TTL\n        except (TypeError, ValueError):\n            expires_in = MCP_OAUTH2_TOKEN_CACHE_DEFAULT_TTL\n\n        ttl: Final = max(\n            expires_in - MCP_OAUTH2_TOKEN_EXPIRY_BUFFER_SECONDS,\n            MCP_OAUTH2_TOKEN_CACHE_MIN_TTL,\n        )\n\n        verbose_logger.info(\n            \"Fetched OAuth2 token for MCP server %s (expires in %ds)\",\n            server.server_id,\n            expires_in,\n        )","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py#L149-L185","documentation":"Raised when the MCP server's OAuth2 token endpoint returns 2xx with a JSON object body, but that object lacks the mandatory 'access_token' key required by RFC 6749. The request itself succeeded — this is a shape validation on the response, distinct from the HTTP-status failure handled just above — and typically means the token_url points at the wrong endpoint or the server issues malformed tokens.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py:167 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the upstream token response contains access_token; verify grant and credentials."],"exampleFix":"Log the token response and confirm 'access_token' is present.","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}