@@ -764,8 +764,15 @@ private function getResourceFromIri(string $data, array $context, string $resour
764764 try {
765765 $ item = $ this ->iriConverter ->getResourceFromIri ($ data , $ context + ['fetch_data ' => true ]);
766766
767- // Type-confusion guard: declared relation class must match the IRI's resource.
768- if (!is_a ($ item , $ resourceClass )) {
767+ // Type-confusion guard: the IRI's resource must satisfy the declared relation type.
768+ // When a union/intersection type is known, validate against it so any member is accepted;
769+ // otherwise fall back to the single declared class.
770+ $ relationType = $ context ['relation_native_type ' ] ?? null ;
771+ $ matchesType = $ relationType instanceof Type
772+ ? $ relationType ->isSatisfiedBy (static fn (Type $ t ): bool => $ t instanceof ObjectType && is_a ($ item , $ t ->getClassName ()))
773+ : is_a ($ item , $ resourceClass );
774+
775+ if (!$ matchesType ) {
769776 throw new NotNormalizableValueException (\sprintf ('The iri "%s" does not reference the correct resource. ' , $ data ));
770777 }
771778
@@ -1227,6 +1234,12 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
12271234 $ context ['resource_class ' ] = $ resourceClass ;
12281235 unset($ context ['uri_variables ' ]);
12291236
1237+ // Validate the IRI target against the declared collection value type so a union
1238+ // (array<Foo|Bar>) accepts an IRI pointing to any of its members, not just the first.
1239+ if ($ collectionValueType instanceof Type) {
1240+ $ context ['relation_native_type ' ] = $ collectionValueType ;
1241+ }
1242+
12301243 try {
12311244 return $ t instanceof Type
12321245 ? $ this ->denormalizeObjectCollection ($ attribute , $ propertyMetadata , $ t , $ resourceClass , $ value , $ format , $ context )
@@ -1249,6 +1262,9 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
12491262 ) {
12501263 $ resourceClass = $ this ->resourceClassResolver ->getResourceClass (null , $ className );
12511264 $ childContext = $ this ->createChildContext ($ this ->createOperationContext ($ context , $ resourceClass , $ propertyMetadata ), $ attribute , $ format );
1265+ if ($ t instanceof Type) {
1266+ $ childContext ['relation_native_type ' ] = $ t ;
1267+ }
12521268
12531269 try {
12541270 return $ this ->denormalizeRelation ($ attribute , $ propertyMetadata , $ resourceClass , $ value , $ format , $ childContext );
0 commit comments