Closed (fixed)
Project:
Menu Normalizer
Version:
2.1.0
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
10 Apr 2026 at 15:54 UTC
Updated:
11 Sep 2026 at 10:50 UTC
Jump to comment: Most recent
When using drupal/menu_normalizer 2.1.0 with Drupal 11 and Symfony 7, a PHP Fatal error occurs on cache rebuild (drush cr) because the normalize() method signature in MenuLinkNormalizer and MenuLinkTreeNormalizer is incompatible with the updated NormalizerInterface in Symfony 7.
PHP Fatal error: Declaration of Drupal\menu_normalizer\Normalizer\MenuLinkNormalizer::normalize($object, $format = null, array $context = []) must be compatible with Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize(mixed $data, ?string $format = null, array $context = []): ArrayObject|array|string|int|float|bool|null in .../menu_normalizer/src/Normalizer/MenuLinkNormalizer.php on line 23
menu_normalizer 2.1.0drush crUpdate the normalize() method signature in both normalizer classes to match Symfony 7's NormalizerInterface:
public function normalize(mixed $object, ?string $format = NULL, array $context = []): array|\ArrayObject|string|int|float|bool|null {
Files to update:
src/Normalizer/MenuLinkNormalizer.phpsrc/Normalizer/MenuLinkTreeNormalizer.phpApply fix and release a new version compatible with Drupal 11 / Symfony 7.
None.
None.
None.
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
brian.seek commentedAdded a MR to update the normalize method signature as suggested.
Comment #5
brian.seek commentedComment #6
brian.seek commentedComment #10
batigolixI opened MR !9 as an alternative to MR !7 by @brian.seek.
It contains the same Symfony 7 fix (
normalize()signature +getSupportedTypes()), minus themeta_data→metadatarename — that belongs in a separate issue. Also updated tests to useMenuLinkMock::createMock()(renamed in D11).Comment #12
fabianderijkConfirmed the fatal on 2.1.0 and confirmed MR !9 resolves it. One note on the reproduction steps: drush cr on its own does not trigger the fatal, because RegisterSerializationClassesCompilerPass only collects tagged service IDs and never loads the classes. The fatal appears as soon as the serializer service is actually instantiated — so it will surface during a cache rebuild only if a module such as jsonapi or rest instantiates it. A minimal reproduction is drush php:eval '\Drupal::service("serializer");' with serialization and menu_normalizer enabled.
I pushed two follow-up commits to the MR branch:
Results after those two commits: PHPUnit 4 tests / 23 assertions pass, phpcs --standard=Drupal,DrupalPractice reports zero issues, drush cr succeeds on a cold cache (cache tables truncated), the serializer instantiates, and normalizing a real MenuLinkTreeElement from the admin menu produces the expected nested structure. No new entries in the PHP watchdog log.
Two pre-existing problems I noticed while testing, both out of scope for this issue — I can open separate issues if wanted:
- delete_route and edit_route are not passed through $this->serializer->normalize(), so raw Url objects end up in the returned array and serialize to "edit_route":{} in JSON.
- menu_normalizer.info.yml does not declare dependencies: - drupal:serialization, even though both normalizers extend a class from that module. drush pmu serialization succeeds while menu_normalizer stays enabled.
With the two follow-up commits included, this is RTBC from my side.
Comment #13
batigolixThanks. I will merge this