Skip to content

fix(symfony): isolate api_platform.property_info tags#8206

Open
soyuka wants to merge 1 commit into
api-platform:4.3from
soyuka:fix/8201
Open

fix(symfony): isolate api_platform.property_info tags#8206
soyuka wants to merge 1 commit into
api-platform:4.3from
soyuka:fix/8201

Conversation

@soyuka
Copy link
Copy Markdown
Member

@soyuka soyuka commented May 28, 2026

Summary

api_platform.property_info extractors were tagged with the global Symfony property_info.* tag namespace in #7969. Symfony's framework property_info service consumes tagged_iterator('property_info.type_extractor') and so picked up API Platform's PhpStanExtractor too — including in the chain used by validator.property_info_loader.

On projects depending on doctrine/persistence / doctrine/common (e.g. Sylius), bin/console cache:clear then crashes inside the validator while walking Doctrine interfaces carrying @template T of object:

Symfony\Component\TypeInfo\Exception\InvalidArgumentException
  Cannot create union with both "object" and class type.
  at UnionType.php:75
  Symfony\Component\TypeInfo\Type::union()
  Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver->getTypeFromNode()
  Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor->getType()
  ApiPlatform\Symfony\Validator\Metadata\Property\ValidatorPropertyMetadataFactory->create()

This PR renames the tags to api_platform.property_info.* (private namespace) and updates the PropertyInfoExtractor composing service to consume the private tags. The framework's property_info is no longer mutated by API Platform, restoring the design intent expressed during #7969 review ("stop touching framework.property_info entirely").

  • src/Symfony/Bundle/Resources/config/api.php — three extractors (reflection / php_doc / phpstan) and the composing PropertyInfoExtractor switch from property_info.* to api_platform.property_info.*.
  • Added testPropertyInfoExtractorsDoNotLeakIntoFrameworkPropertyInfo regression test asserting tag isolation.

Test plan

  • vendor/bin/phpunit --filter testPropertyInfoExtractorsDoNotLeakIntoFrameworkPropertyInfo — passes (15 assertions)
  • vendor/bin/phpunit tests/Symfony/Bundle/ApiPlatformBundleTest.php — passes
  • rm -rf tests/Fixtures/app/var/cache/test && tests/Fixtures/app/console cache:clear --env=test — clears cleanly
  • CI green
  • Reproducer on a Sylius-based project (via composer link of this branch) — confirmed cache:clear exits 0

Fixes #8201
Refs #7969

@soyuka soyuka changed the base branch from main to 4.3 May 28, 2026 14:31
PR api-platform#7969 (shipped in 4.3.6) turned `api_platform.property_info` from
an alias of Symfony's `property_info` into a self-contained service
that registered `ReflectionExtractor`, `PhpDocExtractor`, and
`PhpStanExtractor` tagged with the public `property_info.*` namespace.

Two problems followed:

- Symfony's framework `property_info` consumes the same public tag
  iterator and therefore inherited our `PhpStanExtractor` too —
  including in `validator.property_info_loader`. On projects with
  Doctrine interfaces carrying `@template T of object` (e.g. Sylius),
  `bin/console cache:clear` crashed inside `PhpStanExtractor::getType`
  with "Cannot create union with both \"object\" and class type."
- Tagging our extractors with only a private namespace would have
  fixed the leak but would also have lost inheritance of
  third-party-registered extractors (notably Doctrine's
  `DoctrineExtractor`), breaking serialization and validation
  (embedded objects vs IRIs, "array given" on persist, missing
  constraint violations).

Fix:

- Tag API Platform's 3 fallback extractors with private
  `api_platform.property_info.*` tags only.
- `api_platform.property_info` consumes the private tag iterators.
- Add `PropertyInfoTagPass`, a one-way bridge compiler pass that
  copies every public `property_info.{suffix}` tag (preserving
  attributes such as priority) onto the same service as
  `api_platform.property_info.{suffix}`, skipping services already
  carrying the private tag.

Result: framework `property_info` is untouched (public tags only,
no API Platform extractors leak in), while `api_platform.property_info`
still inherits framework + Doctrine + third-party extractors via the
bridged private tags. The api-platform#7876 fallback path stays intact when
framework's `property_info` is absent.

Fixes api-platform#8201
Refs api-platform#7969 api-platform#7876
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.

New property_info fallback introduced in 4.3.6 causes a bug in configuration loading

1 participant