doctrine/orm · error · InvalidArgumentException

Class "%s" does not exist

Error message

Class "%s" does not exist

What it means

Inside the <options> block of an XML field mapping, Doctrine supports an embedded <object class="..."/> element whose class is instantiated (new $className()) to provide a default value object. XmlDriver::parseObjectElement() requires the class attribute and calls class_exists() on it; a class that cannot be loaded throws InvalidArgumentException naming it.

Source

Thrown at src/Mapping/Driver/XmlDriver.php:724

     * @param SimpleXMLElement $objectElement The XML element.
     *
     * @return object The instantiated object.
     *
     * @throws MappingException If the object specification is invalid.
     * @throws InvalidArgumentException If the class does not exist.
     */
    private function parseObjectElement(SimpleXMLElement $objectElement): object
    {
        $attributes = $objectElement->attributes();

        if (! isset($attributes->class)) {
            throw MappingException::missingRequiredOption('object', 'class');
        }

        $className = (string) $attributes->class;

        if (! class_exists($className)) {
            throw new InvalidArgumentException(sprintf('Class "%s" does not exist', $className));
        }

        return new $className();
    }

    /**
     * Constructs a joinColumn mapping array based on the information
     * found in the given SimpleXMLElement.
     *
     * @param SimpleXMLElement $joinColumnElement The XML element.
     *
     * @return mixed[] The mapping array.
     * @phpstan-return array{
     *                   name: string,
     *                   referencedColumnName: string,
     *                   unique?: bool,
     *                   nullable?: bool,
     *                   onDelete?: string,

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Correct the class attribute to the current fully-qualified class name.
  2. Ensure the class is autoloadable: run composer dump-autoload and check PSR-4 mapping covers its namespace.
  3. If the default-value object is no longer needed, remove the whole <option> entry.

Example fix

<!-- before -->
<option name="default"><object class="App\Util\Money"/></option>

<!-- after (class moved) -->
<option name="default"><object class="App\Value\Money"/></option>
Defensive patterns

Strategy: validation

Validate before calling

$class = (string) $objectElement['class'];
if (! class_exists($class)) {
    throw new InvalidArgumentException("Object option references unknown class {$class}");
}

Prevention

When it happens

Trigger: A mapping like <field ...><options><option name="default"><object class="App\Value\MyDefault"/></option></options></field> where App\Value\MyDefault was renamed, deleted, moved to another namespace, or is not autoloadable in the current project.

Common situations: Refactoring/renaming a value class and forgetting the XML mapping; .dcm.xml files copied between projects; composer autoload maps out of date after moving classes (need dump-autoload).

Related errors


AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21). Data as JSON: /api/errors/46891f0661019050. Report an issue: GitHub.