{"record":{"id":"200d44fa5a5b4ed2","repo":"BerriAI/litellm","slug":"code-is-required-for-authorization-code-grant","errorCode":null,"errorMessage":"code is required for authorization_code grant","messagePattern":"code is required for authorization_code grant","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py","lineNumber":958,"sourceCode":"        upstream_refresh_token: Final = (\n            bridge_upstream_refresh.get_secret_value() if bridge_upstream_refresh is not None else refresh_token\n        )\n        if not upstream_refresh_token:\n            raise HTTPException(\n                status_code=400,\n                detail=\"refresh_token is required for refresh_token grant\",\n            )\n        token_data: dict = {\n            \"grant_type\": \"refresh_token\",\n            \"refresh_token\": upstream_refresh_token,\n            **token_request.body,\n        }\n        refresh_request_scope = scope or bridge_upstream_scope\n        if refresh_request_scope:\n            token_data[\"scope\"] = refresh_request_scope\n    else:\n        if not code:\n            raise HTTPException(\n                status_code=400,\n                detail=\"code is required for authorization_code grant\",\n            )\n        # Interactive dcr_bridge oauth_delegate: the client presents the gateway authorization code the\n        # callback sealed. Recover the SSO user and the real upstream code from it; the upstream exchange\n        # below uses the upstream code, and the mint binds the envelope to the recovered user. Bind the\n        # sealed server to this request so a code minted for one bridge server cannot be spent at another.\n        # A raw upstream code (scripted path) opens to None and the code is used as-is.\n        bridge_identity = open_bridge_authorization_code(code)\n        if bridge_identity is not None:\n            if bridge_identity.mcp_server_id != mcp_server.server_id:\n                raise HTTPException(\n                    status_code=400,\n                    detail=\"Authorization code was issued for a different MCP server\",\n                )\n            code = bridge_identity.upstream_code\n        bridge_token_relay: Final = _dcr_bridge_relays_client_registration(mcp_server)\n        if bridge_token_relay and not redirect_uri:","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py#L940-L976","documentation":"Raised in the MCP OAuth2 token endpoint when grant_type is authorization_code but the request body has no code parameter. Without the one-time authorization code issued by the /authorize step there is nothing to exchange with the upstream token endpoint, so the bridge rejects the request with HTTP 400 immediately.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:958 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Include the authorization code parameter with the authorization_code grant."],"exampleFix":"grant_type=authorization_code&code=<code>","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-14T05:17:10.506Z"}