Misleading ORMInvalidArgumentException message #5254

Closed
opened 2026-01-22 15:02:42 +01:00 by admin · 2 comments
Owner

Originally created by @jonny-no1 on GitHub (Sep 13, 2016).

Originally assigned to: @lcobucci on GitHub.

Given two entities and a random class with similar name (to confuse the developer, but could be anything really):

/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"all"})
     */
    private $groups;

    public function __construct() {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

/** @Entity */
class Group
{
    /**
     * @ManyToMany(targetEntity="User", mappedBy="groups")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

class Group2
{}

If you add an instance of Group2 to User#$groups and try to persist, an exception will be thrown from Doctrine\ORM\UnitOfWork:832:

if (! ($entry instanceof $targetClass->name)) {
  throw ORMInvalidArgumentException::invalidAssociation($targetClass, $assoc, $entry);
}

However, instead of reading like:

Expected value of type "AppBundle\Entity\Group" for association field "AppBundle\Entity\User#$groups", got "AppBundle\Entity\Group2" instead.

It reads like:

Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\User#$groups", got "AppBundle\Entity\Group2" instead.

Simply because the $expectedType isn't set correctly for many-to-many associations in Doctrine\ORM:201:

$expectedType = 'Doctrine\Common\Collections\Collection|array';

if (($assoc['type'] & ClassMetadata::TO_ONE) > 0) {
    $expectedType = $targetClass->getName();
}
Originally created by @jonny-no1 on GitHub (Sep 13, 2016). Originally assigned to: @lcobucci on GitHub. Given two entities and a random class with similar name (to confuse the developer, but could be anything really): ``` php /** @Entity */ class User { // ... /** * @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"all"}) */ private $groups; public function __construct() { $this->groups = new \Doctrine\Common\Collections\ArrayCollection(); } } /** @Entity */ class Group { /** * @ManyToMany(targetEntity="User", mappedBy="groups") */ private $users; public function __construct() { $this->users = new \Doctrine\Common\Collections\ArrayCollection(); } } class Group2 {} ``` If you add an instance of Group2 to User#$groups and try to persist, an exception will be thrown from [Doctrine\ORM\UnitOfWork:832](https://github.com/doctrine/doctrine2/blob/cd11723e6310b5973f50e7d9819c58916721d290/lib/Doctrine/ORM/UnitOfWork.php#L832): ``` php if (! ($entry instanceof $targetClass->name)) { throw ORMInvalidArgumentException::invalidAssociation($targetClass, $assoc, $entry); } ``` However, instead of reading like: ``` Expected value of type "AppBundle\Entity\Group" for association field "AppBundle\Entity\User#$groups", got "AppBundle\Entity\Group2" instead. ``` It reads like: ``` Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\User#$groups", got "AppBundle\Entity\Group2" instead. ``` Simply because the `$expectedType` isn't set correctly for many-to-many associations in [Doctrine\ORM:201](https://github.com/doctrine/doctrine2/blob/cd11723e6310b5973f50e7d9819c58916721d290/lib/Doctrine/ORM/ORMInvalidArgumentException.php#L201): ``` php $expectedType = 'Doctrine\Common\Collections\Collection|array'; if (($assoc['type'] & ClassMetadata::TO_ONE) > 0) { $expectedType = $targetClass->getName(); } ```
admin added the Improvement label 2026-01-22 15:02:42 +01:00
admin closed this issue 2026-01-22 15:02:42 +01:00
Author
Owner

@asiermarques commented on GitHub (Oct 22, 2017):

+1 this is a severe UX problem. That error message must be changed in order to avoid misunderstandings.

@asiermarques commented on GitHub (Oct 22, 2017): +1 this is a severe UX problem. That error message must be changed in order to avoid misunderstandings.
Author
Owner

@lcobucci commented on GitHub (Oct 29, 2017):

@foaly-nr1 could you please send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing.

You can find examples on 388afb46d0/tests/Doctrine/Tests/ORM/Functional/Ticket

@lcobucci commented on GitHub (Oct 29, 2017): @foaly-nr1 could you please send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing. You can find examples on https://github.com/doctrine/doctrine2/tree/388afb46d0cb3ed0c51332e8df0de9e942c2690b/tests/Doctrine/Tests/ORM/Functional/Ticket
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5254