Significant-Gravitas/AutoGPT · error · HTTPException

Unsupported grant_type: {request.grant_type}. Must be 'autho

Error message

Unsupported grant_type: {request.grant_type}. Must be 'authorization_code' or 'refresh_token'

What it means

Thrown by the OAuth 2.0 token endpoint when the grant_type in the token request body is neither 'authorization_code' nor 'refresh_token'. The server only implements those two grant types, so anything else (e.g. 'client_credentials', 'password', or a typo) is rejected with HTTP 400 before any token logic runs.

Source

Thrown at autogpt_platform/backend/backend/api/features/oauth.py:445

        )

        if not new_access_token.token or not new_refresh_token.token:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Failed to generate tokens",
            )

        return TokenResponse(
            token_type="Bearer",
            access_token=new_access_token.token.get_secret_value(),
            access_token_expires_at=new_access_token.expires_at,
            refresh_token=new_refresh_token.token.get_secret_value(),
            refresh_token_expires_at=new_refresh_token.expires_at,
            scopes=list(s.value for s in new_access_token.scopes),
        )

    else:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Unsupported grant_type: {request.grant_type}. "
            "Must be 'authorization_code' or 'refresh_token'",
        )


# ============================================================================
# Token Introspection Endpoint
# ============================================================================


@router.post("/introspect")
async def introspect(
    token: str = Body(description="Token to introspect"),
    token_type_hint: Optional[Literal["access_token", "refresh_token"]] = Body(
        None, description="Hint about token type ('access_token' or 'refresh_token')"
    ),
    client_id: str = Body(description="Client identifier"),

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Set grant_type to exactly 'authorization_code' (with code + redirect_uri) or 'refresh_token' (with refresh_token) in the token request
  2. Verify the request is sent as application/x-www-form-urlencoded with correctly encoded fields
  3. Check the API docs/openapi.json for the token endpoint's accepted grant types before implementing a new flow

Example fix

# before
requests.post(token_url, data={"grant_type": "client_credentials", "client_id": cid, "client_secret": sec})
# after
requests.post(token_url, data={"grant_type": "authorization_code", "code": code, "redirect_uri": redirect, "client_id": cid, "client_secret": sec})
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED_GRANTS = {"authorization_code", "refresh_token"}
assert grant_type in ALLOWED_GRANTS, f"unsupported grant_type: {grant_type!r}"

Type guard

def is_supported_grant(g: str) -> bool:
    return g in {"authorization_code", "refresh_token"}

Try / catch

resp = requests.post(token_url, data=payload)
if resp.status_code == 400 and "Unsupported grant_type" in resp.text:
    raise ValueError(f"Fix grant_type: {payload.get('grant_type')}")

Prevention

When it happens

Trigger: POSTing to the OAuth token endpoint with grant_type=client_credentials, grant_type=password, a misspelled value like 'authorizationCode', or omitting/URL-encoding the grant_type field incorrectly so FastAPI sees an unexpected string.

Common situations: Integrators assuming the platform supports the full OAuth2 grant set; copying example requests from another provider; form-encoding bugs that mangle the grant_type value; custom clients written before checking the API's supported grants.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/3cb8de3516889af9. Report an issue: GitHub.