Skip to content

validation_error_definition schema is incorrect when detecting an error in an array #3790

@silversurfer34

Description

@silversurfer34

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from typing import Optional, List

from fastapi import FastAPI
from pydantic import BaseModel

class SubItem(BaseModel):
    price: float

class Item(BaseModel):
    price_list: Optional[List[SubItem]] = None


app = FastAPI()


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

Description

Run the sample program and call the /items/ api with this body:

{
  "price_list": [
    {
      "price": "zero"
    }
  ]
}

You will get a 422 like this

{
  "detail": [
    {
      "loc": [
        "body",
        "price_list",
        0,
        "price"
      ],
      "msg": "value is not a valid float",
      "type": "type_error.float"
    }
  ]
}

But this 422 response does not follow the validation_error_definition schema :

validation_error_definition = {
    "title": "ValidationError",
    "type": "object",
    "properties": {
        "loc": {"title": "Location", "type": "array", "items": {"type": "string"}},
        "msg": {"title": "Message", "type": "string"},
        "type": {"title": "Error Type", "type": "string"},
    },
    "required": ["loc", "msg", "type"],
}

So the 422 response from fastapi does not respect the schema of the response...

The issue comes from the error in the array, pydantic returns 0 as index of the error, but it is not a string, it is an integer. And it makes sense to return an integer, otherwise we wouldn't know if it is a key in a dict or an index.

As a developer I can workaround this issue by redefining validation_error_definition in my own code

from fastapi.openapi.utils import validation_error_definition

validation_error_definition["properties"] = {
    "loc": {
        "title": "Location", "type": "array", "items": {
            "oneOf": [
                {"type": "string"},
                {"type": "integer"}
            ]
        }
    },
    "msg": {"title": "Message", "type": "string"},
    "type": {"title": "Error Type", "type": "string"},
}

But it would be better to do the change directly in the code. What is your opinion ?

Operating System

Windows

Operating System Details

No response

FastAPI Version

0.68.1

Python Version

3.7.9

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions