Skip to content

ObjectMapper in 4.3.2 causes unintended validation failures on PATCH with input DTO #7886

@Cafeine42

Description

@Cafeine42

API Platform version(s) affected: 4.3.2

Description
Since upgrading to API Platform 4.3.2, PATCH operations using a custom input DTO and a custom output DTO now fail validation on fields that were not sent by the client.
The root cause is that ObjectMapper::map() is now called to hydrate the input DTO from the existing entity before deserialization. This means all DTO properties get populated with the entity's current values, including properties that the client deliberately did not include in the PATCH payload.
Previously (4.3.1), unsent properties on the input DTO remained uninitialized, so validation constraints on those properties were naturally skipped (or passed, as the values were not set). Now, because ObjectMapper pre-fills them from the entity, validation runs against the entity's current state for every property — even those the user has no intention of modifying.
This is a breaking change for any endpoint that allows partial updates on an entity whose current state would not pass full validation on all fields.

How to reproduce

  • Define an entity Foo with properties bar (valid) and baz (currently in a state that would fail validation, e.g. a legacy value).
  • Create a PATCH operation with a dedicated input DTO (FooUpdateInput) that has validation constraints on both bar and baz.
  • Send a PATCH request providing only bar.

Possible Solution

  • Skip ObjectMapper hydration for input DTOs on PATCH operations, restoring the previous behavior where only deserialized (client-sent) properties are present on the DTO.
  • Make ObjectMapper hydration opt-in for input DTOs via an operation attribute (e.g. mapInput: true, mapOutput).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions