Skip to content

Unexpected "Expected data to be an array" error during normalization #8080

@onurkose

Description

@onurkose

API Platform version(s) affected: 3.1.12

Description
I have two entities named as Customer and Address.
Address records belongs to Customer records, with OneToMany type relationship.
Customer records does also have an invoiceAddress property which is ManyToOne type relationship.

Entities have these fragments defined for them;

fragment AddressBaseFragment on Address {
  id
  address

  owner {
    ...CustomerBaseFragment
  }
}

fragment CustomerBaseFragment on Customer {
  id
  name
  invoiceAddress {
    ...AddressBaseFragment
  }
}

When I run a collection query like this for Address entity, I started to receive "Expected data to be an array" exception;

query addresses {
  addresses {
    ...AddressBaseFragment
  }
}

How to reproduce
Just two entities in a circular relationship.

#[ApiResource(
    paginationEnabled: false,
    graphQlOperations: [
        new QueryCollection(),
        new Query(),
        new Mutation(name: 'create'),
        new Mutation(name: 'update'),
        new Mutation(name: 'delete')
    ],
    extraProperties: [
        'standard_put' => true,
    ]
)]
class Address
{
    #[ORM\Id, ORM\GeneratedValue(strategy: 'IDENTITY'), ORM\Column(type: 'integer')]
    protected ?int $id = null;

    #[ORM\Column(type: 'string', length: 255)]
    protected $address;

    #[ORM\ManyToOne(targetEntity: Customer::class, cascade: ['persist'], inversedBy: 'addresses')]
    #[ORM\JoinColumn(nullable: false)]
    protected $owner;

    public function getAddress(): ?string
    {
        return $this->address;
    }

    public function setAddress(string $address): self
    {
        $this->address = $address;

        return $this;
    }

    public function getOwner(): ?Customer
    {
        return $this->owner;
    }

    public function setOwner(?Customer $owner): self
    {
        $this->owner = $owner;

        return $this;
    }
}
#[ApiResource(
    paginationEnabled: false,
    graphQlOperations: [
        new QueryCollection(),
        new Query(),
        new Mutation(name: 'create'),
        new Mutation(name: 'update'),
        new Mutation(name: 'delete')
    ],
    extraProperties: [
        'standard_put' => true,
    ]
)]
class Customer
{
    #[ORM\Id, ORM\GeneratedValue(strategy: 'IDENTITY'), ORM\Column(type: 'integer')]
    protected ?int $id = null;
    
    #[ORM\ManyToOne(targetEntity: Address::class, cascade: ['persist'])]
    protected $invoiceAddress;

    #[ORM\OneToMany(mappedBy: 'owner', targetEntity: Address::class, orphanRemoval: true)]
    protected $addresses;

    public function __construct()
    {
        $this->addresses = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getInvoiceAddress(): ?Address
    {
        return $this->invoiceAddress;
    }

    public function setInvoiceAddress(?Address $invoiceAddress): self
    {
        $this->invoiceAddress = $invoiceAddress;

        return $this;
    }

    public function getAddresses(): Collection
    {
        return $this->addresses;
    }

    public function addAddress(Address $address): self
    {
        if (!$this->addresses->contains($address)) {
            $this->addresses[] = $address;
            $address->setOwner($this);
        }

        return $this;
    }

    public function removeAddress(Address $address): self
    {
        if ($this->addresses->removeElement($address)
            && $address->getOwner() === $this
        ) {
            $address->setOwner(null);
        }

        return $this;
    }
}

Possible Solution

Additional Context
When I remove invoiceAddress from the Customer fragment, the exception disappears;

// this works
fragment CustomerBaseFragment on Customer {
  id
  name
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions