-
-
Notifications
You must be signed in to change notification settings - Fork 961
ObjectMapper in 4.3.2 causes unintended validation failures on PATCH with input DTO #7886
Description
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).