Resolving FastAPI 422 Error: Value is not a valid dict

Updated: January 2, 2024 By: Guest Contributor Post a comment

The Problem

The FastAPI 422 Unprocessable Entity error often occurs when an endpoint receives data in an incorrect format or the request does not align with the data schema defined. If you’re trying to solve this issue, it’s critical to understand that it is frequently related to Pydantic models or the type annotations utilized in the endpoint. The error indicates that the input data cannot be coerced into a valid dictionary as expected by the underlying Pydantic models for request validation.

Solutions

Solution 1: Validate Request Body

Ensure your request body matches the Pydantic model’s structure. Below are the main points:

  • Check the request body schema: Match it with the schema defined in your Pydantic model.
  • Update request data: Modify the request to fulfill the model’s requirements.

Example:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

Advantages: Straightforward solution; often resolves the issue immediately.

Limitations: Relies on clients to send the correct data format.

Solution 2: Modify Pydantic Model

Update the Pydantic model to accommodate variable input structures. Use `typing.Optional` or `typing.Union` to allow for different types or optional fields.

What to do: Allow None for optional fields or support multiple types.

Example:

from typing import Optional, Union
from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: Union[float, str]
    tax: Optional[float] = None

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

Advantages: Provides flexibility in the request data that is accepted.

Limitations: May lead to a less strict API design and unintentional errors.

Solution 3: Custom Request Validator

Create a custom validator in your Pydantic model to handle data conversion or validation logic explicitly. This is done within the Pydantic model using the `@validator` decorator.

Example:

from pydantic import BaseModel, validator
from fastapi import FastAPI

class Item(BaseModel):
    name: str
    price: float

    @validator('price')
    def price_must_be_float(cls, v):
        if isinstance(v, float):
            return v
        raise ValueError('Price must be a float')

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

Advantages: More control over input validation; clear error messages.

Limitations: Adds complexity to the model; larger codebase for maintenance.

If you encounter a 422 error in FastAPI, the error generally indicates a discrepancy between the request sent to the server and the expected schema. Using one of these solutions can help resolve the error and ensure that your API endpoints are receiving and processing data correctly. The balances between strict schemas and flexibility depend on your specific requirements and the expected use cases of your API.