This is an issue when a FastAPI endpoint raises HTTPException with specific status codes, but these status codes are not documented in the endpoint decorator’s responses parameter.

Why is this an issue?

FastAPI automatically generates OpenAPI (Swagger) documentation for your API endpoints. This documentation is crucial for API consumers to understand how to interact with your API, including what error responses they might encounter.

When you raise HTTPException in your endpoint code, FastAPI will return the specified HTTP status code and error details at runtime. However, unless you explicitly document these exceptions in the responses parameter of your endpoint decorator, they won’t appear in the automatically generated API documentation.

This creates a gap between what your API actually does and what the documentation says it does. API consumers looking at your OpenAPI specification will not see these error responses, making it harder for them to:

The responses parameter in FastAPI endpoint decorators exists specifically to document all possible HTTP responses, including error cases. By documenting your HTTPException raises, you ensure that the OpenAPI specification accurately reflects your API’s behavior, improving the developer experience for anyone consuming your API.

What is the potential impact?

When HTTPException responses are not documented:

How to fix it in FastAPI

Add the responses parameter to your endpoint decorator, documenting each HTTPException status code that can be raised. The key should be the status code, and the value should be a dictionary with at least a description field explaining when this error occurs.

Code examples

Noncompliant code example

@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id not in users:
        raise HTTPException(status_code=404, detail="User not found")  # Noncompliant
    return users[user_id]

Compliant solution

@app.get(
    "/users/{user_id}",
    responses={404: {"description": "User not found"}}
)
def get_user(user_id: int):
    if user_id not in users:
        raise HTTPException(status_code=404, detail="User not found")
    return users[user_id]

For endpoints that can raise multiple different HTTPException status codes, document all of them in the responses parameter. Each status code should have a clear description of when it occurs.

Noncompliant code example

@app.post("/items")
def create_item(item: Item):
    if not item.name:
        raise HTTPException(status_code=422, detail="Name is required")  # Noncompliant
    if len(item.name) > 100:
        raise HTTPException(status_code=422, detail="Name too long")  # Noncompliant
    return item

Compliant solution

@app.post(
    "/items",
    responses={
        422: {"description": "Validation error: Name is required or too long"}
    }
)
def create_item(item: Item):
    if not item.name:
        raise HTTPException(status_code=422, detail="Name is required")
    if len(item.name) > 100:
        raise HTTPException(status_code=422, detail="Name too long")
    return item

You can provide more detailed response documentation by including a model or additional fields. This is especially useful for complex error responses.

Noncompliant code example

@app.get("/")
def home():
    raise HTTPException(status_code=400, detail="Bad Request")  # Noncompliant

Compliant solution

@app.get(
    "/",
    responses={
        400: {
            "description": "Bad Request",
            "content": {
                "application/json": {
                    "example": {"detail": "Bad Request"}
                }
            }
        }
    }
)
def home():
    raise HTTPException(status_code=400, detail="Bad Request")

Resources

Documentation