From ff041c0e0a5ea9570338f1a9666778df492d4755 Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 4 Jun 2026 13:55:47 +0200 Subject: [PATCH] fix(serializer): clarify nested-document error with actionable hints The previous "Use IRIs instead." hint only told users one of two possible remedies. When a developer intends nested embedding, the real fix is to add matching denormalization groups on the related resource (and, for to-many relations, adder/remover methods on the parent), not to switch to IRIs. Expand the message to surface both options so the failure mode is self-diagnosing. Fixes #8077 --- src/Serializer/AbstractItemNormalizer.php | 2 +- src/Serializer/Tests/AbstractItemNormalizerTest.php | 2 +- tests/Functional/Hal/ProblemTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index 4ef86f8e24..cf7e46637a 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -756,7 +756,7 @@ protected function denormalizeRelation(string $attributeName, ApiProperty $prope throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" attribute must be "array" (nested document) or "string" (IRI), "%s" given.', $attributeName, \gettype($value)), $value, ['array', 'string'], $context['deserialization_path'] ?? null, true); } - throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Nested documents for attribute "%s" are not allowed. Use IRIs instead.', $attributeName), $value, ['array', 'string'], $context['deserialization_path'] ?? null, true); + throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Nested documents for attribute "%s" are not allowed. Provide an IRI, or enable nested writes by adding matching denormalization groups on the related resource (and, for to-many relations, define adder/remover methods on the parent class).', $attributeName), $value, ['array', 'string'], $context['deserialization_path'] ?? null, true); } private function getResourceFromIri(string $data, array $context, string $resourceClass): ?object diff --git a/src/Serializer/Tests/AbstractItemNormalizerTest.php b/src/Serializer/Tests/AbstractItemNormalizerTest.php index c9c7c097a4..694e186641 100644 --- a/src/Serializer/Tests/AbstractItemNormalizerTest.php +++ b/src/Serializer/Tests/AbstractItemNormalizerTest.php @@ -1422,7 +1422,7 @@ public function testDeserializationPathForNotFoundResource(): void public function testInnerDocumentNotAllowed(): void { $this->expectException(UnexpectedValueException::class); - $this->expectExceptionMessage('Nested documents for attribute "relatedDummy" are not allowed. Use IRIs instead.'); + $this->expectExceptionMessage('Nested documents for attribute "relatedDummy" are not allowed. Provide an IRI, or enable nested writes by adding matching denormalization groups on the related resource (and, for to-many relations, define adder/remover methods on the parent class).'); $data = [ 'relatedDummy' => [ diff --git a/tests/Functional/Hal/ProblemTest.php b/tests/Functional/Hal/ProblemTest.php index 4c5e513676..458b1c8714 100644 --- a/tests/Functional/Hal/ProblemTest.php +++ b/tests/Functional/Hal/ProblemTest.php @@ -71,7 +71,7 @@ public function testNestedRelationDocumentReturns400Problem(): void $body = $response->toArray(false); $this->assertSame('/errors/400', $body['type']); $this->assertSame('An error occurred', $body['title']); - $this->assertSame('Nested documents for attribute "relatedDummy" are not allowed. Use IRIs instead.', $body['detail']); + $this->assertSame('Nested documents for attribute "relatedDummy" are not allowed. Provide an IRI, or enable nested writes by adding matching denormalization groups on the related resource (and, for to-many relations, define adder/remover methods on the parent class).', $body['detail']); $this->assertArrayHasKey('trace', $body); } }