Skip to content

Handling RequestValidationError for PydanticUndefinedType with empty list type query parameters #9920

@rakuzen25

Description

@rakuzen25

Privileged issue

  • I'm @tiangolo or he asked me directly to create an issue here.

Issue Content

Although I have not contacted tiangolo, I received an approval from @Kludex to create an issue for this.

Right now there is a problem with how FastAPI handles RequestValidationError when a list query parameter is empty with Pydantic v2. Quoting Kludex's original comment:

This is a bug.

It's not related to UUID, but with any list:

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/test")
def get_test(device_ids: list[int] = Query()) -> int:
    return 1


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(f"{__name__}:app", reload=True)

It's a FastAPI issue, not Pydantic. Thanks for reporting it. 👍

To provide some context, when the RequestValidationError is raised, the default handler tries to serialise the error with jsonable_encoder, which calls either dict or vars.

https://github.com/tiangolo/fastapi/blob/f7e3559bd5997f831fb9b02bef9c767a50facbc3/fastapi/exception_handlers.py#L20-L26

https://github.com/tiangolo/fastapi/blob/f7e3559bd5997f831fb9b02bef9c767a50facbc3/fastapi/encoders.py#L229-L238

However, when a list query parameter is empty, Pydantic somehow returns a PydanticUndefinedType that jsonable_encoder cannot understand, raising an uncaught exception (traceback from @ivankoster's original comment)

Traceback (most recent call last):
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\routing.py", line 66, in app
    response = await func(request)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\routing.py", line 271, in app
    raise RequestValidationError(_normalize_errors(errors), body=body)
fastapi.exceptions.RequestValidationError: [{'type': 'list_type', 'loc': ('query', 'device_ids'), 'msg': 'Input should be a valid list', 'input': PydanticUndefined, 'url': 'https://errors.pydantic.dev/2.0.3/v/list_type'}]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\encoders.py", line 230, in jsonable_encoder
    data = dict(obj)
TypeError: 'pydantic_core._pydantic_core.PydanticUndefinedType' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\encoders.py", line 235, in jsonable_encoder
    data = vars(obj)
TypeError: vars() argument must have __dict__ attribute

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 426, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
    raise exc
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\starlette\middleware\exceptions.py", line 88, in __call__
    response = await handler(request, exc)
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\exception_handlers.py", line 26, in request_validation_exception_handler
    content={"detail": jsonable_encoder(exc.errors())},
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\encoders.py", line 209, in jsonable_encoder
    jsonable_encoder(
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\encoders.py", line 195, in jsonable_encoder
    encoded_value = jsonable_encoder(
  File "C:\Users\Ivan\workspace\redacted\.venv\lib\site-packages\fastapi\encoders.py", line 238, in jsonable_encoder
    raise ValueError(errors) from e
ValueError: [TypeError("'pydantic_core._pydantic_core.PydanticUndefinedType' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions