Problem/Motivation

Since Drupal core 11.4.0, Drupal\serialization\Normalizer\ComplexDataNormalizer::normalize() narrowed its return type from array|string|int|float|bool|\ArrayObject|null to a strict array (see https://www.drupal.org/node/3588047 for the full list of affected normalizer return-type changes).

custom_field_jsonapi's EntityReferenceNormalizer extends ComplexDataNormalizer directly but still declares the old, wider return type and returns NULL in one branch. Both are now invalid: PHP rejects the wider override as incompatible with the parent (fatal at class-load time), and even with a matching type, returning NULL from a method declared : array would throw a TypeError.

This is a full site-breaking fatal error — the class fails to load at all, so it can crash container compilation for any request/command.

Note: the other five normalizers in custom_field_jsonapi (DateTimeNormalizer, StringLongNormalizer, DateRangeNormalizer, TimeRangeNormalizer, UriNormalizer) extend PrimitiveDataNormalizer, whose actual normalize() implementation comes from SchematicNormalizerTrait, which core did not narrow — so only EntityReferenceNormalizer is affected.

Steps to reproduce

  1. Require drupal/core: ^11.4 alongside drupal/custom_field: 4.0.8 with a content entity_reference or image custom field using the custom_field_jsonapi submodule.
  2. Run drush cache:rebuild or hit any request that loads Drupal\custom_field_jsonapi\Normalizer\EntityReferenceNormalizer.
  3. Observe:
Fatal error: Declaration of Drupal\custom_field_jsonapi\Normalizer\EntityReferenceNormalizer::normalize($object, $format = null, array $context = []): ArrayObject|array|string|int|float|bool|null must be compatible with Drupal\serialization\Normalizer\ComplexDataNormalizer::normalize($object, $format = null, array $context = []): array

Proposed resolution

Narrow EntityReferenceNormalizer::normalize()'s return type to : array (matching the parent) and change the return NULL; branch to return [];, consistent with how ComplexDataNormalizer itself already returns an empty array rather than NULL when there is nothing to normalize.

Patch attached below (also posting to the issue fork branch). Tested against Drupal core 11.4.0 — resolves the fatal error and drush status reports a successful bootstrap again.

diff --git a/modules/custom_field_jsonapi/src/Normalizer/EntityReferenceNormalizer.php b/modules/custom_field_jsonapi/src/Normalizer/EntityReferenceNormalizer.php
index 20db511b2fe..b0e780f4fe4 100644
--- a/modules/custom_field_jsonapi/src/Normalizer/EntityReferenceNormalizer.php
+++ b/modules/custom_field_jsonapi/src/Normalizer/EntityReferenceNormalizer.php
@@ -35,7 +35,7 @@ public function __construct(EntityRepositoryInterface $entity_repository) {
   /**
    * {@inheritdoc}
    */
-  public function normalize($object, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|null {
+  public function normalize($object, $format = NULL, array $context = []): array {
     $entity = $object->getEntity();
     if ($entity instanceof EntityInterface) {
       // Set the entity in the correct language.
@@ -99,7 +99,7 @@ public function normalize($object, $format = NULL, array $context = []): array|s
       return $attributes;
     }
 
-    return NULL;
+    return [];
   }
 
   /**

Remaining tasks

None — patch is complete and tested.

User interface changes

None.

API changes

None — return type is narrowed to match the already-declared parent contract; the only behavioral change is returning [] instead of NULL when there is no entity to normalize, which was already required by the parent class's contract.

Data model changes

None.

Issue summary and MR created with AI assistance.

Command icon Show commands

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

freelock created an issue. See original summary.

freelock’s picture

Status: Active » Needs review

This is fixing at least the initial whitescreen issues for me -- not sure if there's anything that depends on these other return types...

martijn de wit made their first commit to this issue’s fork.

martijn de wit’s picture

Added a test, so this won't happen in the future.

Patch look good to me

martijn de wit’s picture

Status: Needs review » Reviewed & tested by the community
longwave’s picture

Also ran into this on an 11.4 upgrade, RTBC+1.

  • apmsooner committed f81d60a8 on 4.0.x authored by freelock
    fix: #3608027 Fatal error: Declaration of EntityReferenceNormalizer::...
apmsooner’s picture

Status: Reviewed & tested by the community » Fixed

Thanks all, will be in upcoming release this week.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.