from datetime import UTC, datetime
from litestar import post
from litestar.plugins.pydantic import PydanticDTO
from litestar.testing import create_test_client
from pydantic import AwareDatetime, BaseModel
class MyModel(BaseModel):
dt: AwareDatetime
class MyDTO(PydanticDTO[MyModel]):
pass
@post("/incoming", dto=MyDTO, sync_to_thread=False)
def incoming_handler(data: MyModel) -> None:
pass
@post("/outgoing", dto=MyDTO, sync_to_thread=False)
def outgoing_handler() -> MyModel:
return MyModel(dt=datetime.now(tz=UTC))
if __name__ == "__main__":
with create_test_client(route_handlers=[incoming_handler, outgoing_handler]) as client:
data = MyModel(dt=datetime.now(tz=UTC))
response = client.post("/outgoing") # Works fine
response = client.post("/incoming", content=data.model_dump_json()) # Fails
INFO - 2025-11-28 18:20:26,753 - httpx - _client - HTTP Request: POST http://testserver.local/outgoing "HTTP/1.1 201 Created"
ERROR - 2025-11-28 18:20:26,755 - litestar - config - Uncaught exception (connection_type=http, path='/incoming'):
Traceback (most recent call last):
File "toy/.venv/lib/python3.13/site-packages/litestar/serialization/msgspec_hooks.py", line 139, in default_deserializer
raise TypeError(f"Unsupported type: {type(value)!r}")
TypeError: Unsupported type: <class 'str'>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "toy/.venv/lib/python3.13/site-packages/litestar/serialization/msgspec_hooks.py", line 209, in decode_json
return msgspec.json.decode(
~~~~~~~~~~~~~~~~~~~^
value,
^^^^^^
...<5 lines>...
strict=strict,
^^^^^^^^^^^^^^
)
^
msgspec.ValidationError: Unsupported type: <class 'str'> - at `$.dt`
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "toy/.venv/lib/python3.13/site-packages/litestar/routes/http.py", line 163, in _call_handler_function
kwargs = await parameter_model.to_kwargs(connection=request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/_kwargs/kwargs_model.py", line 386, in to_kwargs
await extractor(output, connection)
File "toy/.venv/lib/python3.13/site-packages/litestar/_kwargs/extractors.py", line 486, in extractor
values["data"] = await data_extractor(connection)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/_kwargs/extractors.py", line 504, in dto_extractor
return data_dto(connection).decode_bytes(body)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/plugins/pydantic/dto.py", line 104, in decode_bytes
return super().decode_bytes(value)
~~~~~~~~~~~~~~~~~~~~^^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/dto/base_dto.py", line 120, in decode_bytes
return backend.populate_data_from_raw(value, self.asgi_connection)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/dto/_codegen_backend.py", line 137, in populate_data_from_raw
return self._transfer_to_model_type(self.parse_raw(raw, asgi_connection))
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "toy/.venv/lib/python3.13/site-packages/litestar/dto/_backend.py", line 244, in parse_raw
result = decode_json(value=raw, target_type=self.annotation, type_decoders=type_decoders, strict=False)
File "toy/.venv/lib/python3.13/site-packages/litestar/serialization/msgspec_hooks.py", line 219, in decode_json
raise SerializationException(str(msgspec_error)) from msgspec_error
litestar.exceptions.base_exceptions.SerializationException: Unsupported type: <class 'str'> - at `$.dt`
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "toy/.venv/lib/python3.13/site-packages/litestar/middleware/_internal/exceptions/middleware.py", line 158, in __call__
await self.app(scope, receive, capture_response_started)
File "toy/.venv/lib/python3.13/site-packages/litestar/_asgi/asgi_router.py", line 100, in __call__
await asgi_app(scope, receive, send)
File "toy/.venv/lib/python3.13/site-packages/litestar/routes/http.py", line 81, in handle
response = await self._get_response_for_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
scope=scope, request=request, route_handler=route_handler, parameter_model=parameter_model
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "toy/.venv/lib/python3.13/site-packages/litestar/routes/http.py", line 133, in _get_response_for_request
return await self._call_handler_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
scope=scope, request=request, parameter_model=parameter_model, route_handler=route_handler
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "toy/.venv/lib/python3.13/site-packages/litestar/routes/http.py", line 165, in _call_handler_function
raise ClientException(str(e)) from e
litestar.exceptions.http_exceptions.ClientException: 400: Unsupported type: <class 'str'> - at `$.dt`
INFO - 2025-11-28 18:20:26,756 - httpx - _client - HTTP Request: POST http://testserver.local/incoming "HTTP/1.1 400 Bad Request"
Description
When using Pydantic v2 with
PydanticDTO, fields typed aspydantic.AwareDatetimeare not correctly serialized. They should be treated as strings during the DTO transfer phase, but they are currently missing from the_down_typesmapping.URL to code causing the issue
No response
MCVE
Steps to reproduce
AwareDatetime.PydanticDTO.Screenshots
No response
Logs
Litestar Version
Litestar 2.18.0
Python 3.13.0
Platform