Skip to content

Bug: PydanticDTO performs unexpected datetime validation #4481

@raidzin

Description

@raidzin

Description

When using PydanticDTO, additional stricter validation is added for the datetime fields. This validation requires an exact match with RFC3339, although pydantic allows for inaccuracies.

Why is this bad? For example, the native html input tag with the type datetime-local formats dates as YYYY-MM-DDTHH:mm, which is suitable for pydantic fields, but with PydanticDTO it stops working.

URL to code causing the issue

No response

MCVE

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "litestar",
#     "pydantic",
# ]
# ///
import logging
from datetime import datetime
from typing import Annotated

from litestar import Litestar, post
from litestar.contrib.pydantic import PydanticDTO
from litestar.dto import DTOConfig
from litestar.testing import TestClient
from pydantic import BaseModel

logging.getLogger('httpx').propagate = False


class Foo(BaseModel):
    date: datetime


dto_config = DTOConfig()
FooDTO = PydanticDTO[Annotated[Foo, dto_config]]


@post('/with-dto', dto=FooDTO)
async def create_foo_with_dto(data: Foo) -> None:
    pass


@post('/without-dto')
async def create_foo_without_dto(data: Foo) -> None:
    pass


app = Litestar(
    route_handlers=[
        create_foo_with_dto,
        create_foo_without_dto,
    ],
)


def check_datetime(url: str, test_client: TestClient) -> None:
    response = test_client.post(
        url=url,
        json={'date': '2025-05-23T12:20'},
    )
    match response.status_code:
        case 201:
            print(f'OK: {url}')
        case status:
            print(f'ERROR: {url}, STATUS: {status}, JSON: {response.json()}')


def main() -> None:
    test_client = TestClient(app)
    check_datetime('/without-dto', test_client)
    check_datetime('/with-dto', test_client)


if __name__ == '__main__':
    main()

Steps to reproduce

  1. Run MCVE with uv run ...
  2. Scroll down to "ERROR: /with-dto, STATUS: 400, JSON: {'status_code': 400, 'detail': 'Invalid RFC3339 encoded datetime - at $.date'}"
  3. See error

Screenshots

No response

Logs

OK: /without-dto
ERROR: /with-dto, STATUS: 400, JSON: {'status_code': 400, 'detail': 'Invalid RFC3339 encoded datetime - at `$.date`'}

Litestar Version

2.18.0

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bug 🐛This is something that is not working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions