Skip to content

fix(serializer): discriminated input patch fix - #8427

Open
aurimasrimkusnfq wants to merge 2 commits into
api-platform:4.3from
aurimasrimkusnfq:it-1280-discriminated-input-patch-fix
Open

fix(serializer): discriminated input patch fix#8427
aurimasrimkusnfq wants to merge 2 commits into
api-platform:4.3from
aurimasrimkusnfq:it-1280-discriminated-input-patch-fix

Conversation

@aurimasrimkusnfq

Copy link
Copy Markdown
Q A
Branch? 4.3
Tickets Fixes #8414
License MIT
Doc PR N/A

Additional merge PATCH fix on top of #8424

soyuka and others added 2 commits July 26, 2026 09:23
… DTO subclass

When an operation uses a plain (non-ApiResource) input DTO carrying a
Serializer DiscriminatorMap, the normalizer pins resource_class to the
abstract input base. The discriminator resolves the concrete subclass for
instantiation, but constructor/setter argument metadata was still read from
the abstract base, so an object-typed argument declared only on the subclass
resolved to no type and its nested payload was passed as a raw array,
triggering a TypeError (HTTP 500).

Pin resource_class to the discriminator-resolved concrete class on the input
path so subclass-only argument types are found and denormalized.

Regression from api-platform#7779 (4.2.17).

Fixes api-platform#8414
@aurimasrimkusnfq aurimasrimkusnfq changed the title It 1280 discriminated input patch fix fix(serializer): discriminated input patch fix Jul 27, 2026
@soyuka

soyuka commented Aug 16, 2026

Copy link
Copy Markdown
Member

Thanks — reviewed this against #8424 and this PR supersedes it: your branch already carries soyuka's commit 761563f as its first commit, and generalizes it to cover the PATCH path that #8424 provably misses (at AbstractItemNormalizer.php:267 the discriminator resolution is skipped entirely when objectToPopulate !== null, so the $context['resource_class'] !== $type guard never fires). #8424 will be closed as superseded once this lands — authorship is preserved either way.

One change requested before merge:

$concreteClass = null !== $objectToPopulate ? $objectToPopulate::class : $type;

Please use $this->getObjectClass($objectToPopulate) instead of $objectToPopulate::class.

AbstractItemNormalizer pulls in ClassInfoTrait (:68) specifically to unwrap Doctrine proxies, and uses it everywhere else it needs a class name — :91, :106, :149. With input: SomeEntity::class where the provider returns a managed reference, ::class yields Proxies\__CG__\SomeEntity, which then gets pinned into $context['resource_class'] and breaks every downstream propertyMetadataFactory->create() call. Narrow scenario, but it is exactly what the helper exists to prevent.

Non-blocking, but worth a look while you are in there: the new Patch on ChannelResource declares output: NotificationChannelInput::class while processPatch() returns a ChannelResource. That looks incoherent and unrelated to the input-side bug — is it load-bearing for the test, or carried over from your application?

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.

2 participants