Skip to content

object|<Class> docblocks in DispatchTrait break metadata warmup under symfony/type-info 7.4 (Cannot create union with both "object" and class type) #8312

Description

@schmunk42

API Platform version

4.3.13

PHP version

8.4

Description

api-platform/core 4.3 ships redundant union docblocks of the form
object|<Class> in its own source:

  • src/Symfony/Messenger/DispatchTrait.php:28@param object|Envelope $message
  • src/Doctrine/Common/Messenger/DispatchTrait.php:28@param object|Envelope $message

With symfony/type-info 7.4 installed, the PhpStanExtractor that API Platform
wires as api_platform.property_info.php_stan_extractor throws an Exception while building
the type graph whenever it parses such a docblock:

Symfony\Component\TypeInfo\Exception\InvalidArgumentException:
Cannot create union with both "object" and class type.
  at vendor/symfony/type-info/Type/UnionType.php:75

object|Envelope is redundant — object already subsumes every class type.
The legacy symfony/property-info Type model tolerated this; symfony/type-info
7.4 rejects it hard.

This regressed cache:clear / routing warmup on the Symfony 7.3 → 7.4 bump.

Relation to #8201 / #8206

PR #8206 (released in 4.3.10) isolated the framework property_info service
from API Platform's extractors via private api_platform.property_info.* tags +
a bridge compiler pass. That fixed the path where API Platform's PhpStanExtractor
leaked into the framework service (Sylius @template T of object crash).

It does not cover this case: API Platform's own PhpStanExtractor still
parses object|<Class> docblocks during metadata warmup and hits the same
type-info exception. The remaining 4.3 path is still affected.

How to reproduce

Minimal standalone reproduction (public packages only, no app kernel needed):
https://gist.github.com/schmunk42/3357f3d0fdffe11e977812900355cefd

composer install
php repro.php
PHP            : 8.4.22
api-platform/core: v4.3.13
symfony/type-info: v7.4.9
symfony/property-info: v7.4.8
------------------------------------------------------------
[KO]  Symfony\Component\TypeInfo\Exception\InvalidArgumentException: Cannot create union with both "object" and class type.
      thrown from: .../symfony/type-info/Type/UnionType.php:75

The gist invokes the exact extractor API Platform wires as
api_platform.property_info.php_stan_extractor directly
Title:


on a property whose
docblock mirrors the DispatchTrait shape (@var object|Envelope).

You can also confirm the offending docblocks directly:

grep -rn "object|Envelope" vendor/api-platform/core/src
# src/Doctrine/Common/Messenger/DispatchTrait.php:28
# src/Symfony/Messenger/DispatchTrait.php:28

Possible solution

Drop the redundant |Envelope from both DispatchTrait docblocks — the
method already declares object $message / : Envelope in the signature, so
the docblock carries no extra information:

-    /**
-     * @param object|Envelope $message
-     */
     private function dispatch(object $message): Envelope

(or @param object $message if a docblock is desired). This keeps the source
free of redundant unions that symfony/type-info 7.4 rejects.

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