Skip to content

fix(serializer): report enum backing type in denormalization violations#8389

Open
soyuka wants to merge 1 commit into
api-platform:4.3from
soyuka:fix/enum-denormalization-message-8388
Open

fix(serializer): report enum backing type in denormalization violations#8389
soyuka wants to merge 1 commit into
api-platform:4.3from
soyuka:fix/enum-denormalization-message-8388

Conversation

@soyuka

@soyuka soyuka commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

Fixes #8388.

When a wrong-typed value is sent for a nullable backed enum property (e.g. ?Status), collectDenormalizationErrors produced the violation message:

{ "propertyPath": "status", "message": "This value should be of type Status|null." }

Status|null is the internal PHP type: it appears nowhere in the OpenAPI schema, is not something a JSON consumer can send, and names none of the accepted values. This is a regression from the TypeInfo migration (#6979); on 4.1.x the same request named int|string + a hint.

Root cause

AbstractItemNormalizer delegates a nullable backed enum to BackedEnumNormalizer, which throws an actionable exception (expectedTypes = ['int','string'], useMessageForUser = true, message naming the enum). The post-loop error block then rewrapped it, replacing expectedTypes with (string) $types (["Status","null"]) and dropping the user-facing hint flag. DeserializeProvider renders implode('|', expectedTypes)Status|null, hint gone.

Fix

Now {"status": true} on a ?Status (string-backed, nullable) property yields:

{
  "propertyPath": "status",
  "message": "This value should be of type string|null.",
  "hint": "The data is neither an integer nor a string, you should pass an integer or a string that can be parsed as an enumeration case of type Status."
}

Tests

Added testWrongTypeForBackedEnumReportsAcceptedScalarTypes to EnumDenormalizationValidationTest (the existing #8183 test file). Existing enum + ValidationTest message assertions stay green.

Only validation message content changes — no HTTP status, propertyPath, constraint-code, or response-shape change; non-breaking, targeted at 4.3.

When a wrong-typed value is sent for a nullable backed enum property (e.g.
`?Status`), collectDenormalizationErrors produced the violation message
"This value should be of type Status|null." — the internal PHP type, which
appears nowhere in the OpenAPI schema and names none of the accepted values.

AbstractItemNormalizer delegates nullable backed enums to BackedEnumNormalizer,
which throws an actionable exception (accepted scalars + hint). The post-loop
block then rewrapped it, replacing its expectedTypes with `(string) $types`
("Status|null") and dropping the user-facing hint flag.

Preserve the hint flag when the failure comes from an object/enum normalizer,
and in DeserializeProvider render a BackedEnum expected type as its JSON-visible
backing scalar ("string"/"int") instead of the enum FQCN. The enum class stays
in expectedTypes so the 400->422 promotion (api-platform#8183) keeps working.

Now `{"status": true}` on a `?Status` property yields
"This value should be of type string|null." plus the enum hint.

Closes api-platform#8388
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant