doctrine/orm · error · InvalidArgumentException

Unknown class {className}

Error message

Unknown class {className}

What it means

DatabaseDriver builds its class-to-table map by reverse engineering the schema: every table name is inflected into a candidate class name (plus explicit setClassNameForTable() overrides and setNamespace() prefixes). loadMetadataForClass() only accepts class names present in that map; any other name throws InvalidArgumentException('Unknown class ...').

Source

Thrown at src/Mapping/Driver/DatabaseDriver.php:186

     * @param ClassMetadata<T> $metadata
     *
     * @template T of object
     */
    public function loadMetadataForClass(string $className, PersistenceClassMetadata $metadata): void
    {
        if (! $metadata instanceof ClassMetadata) {
            throw new TypeError(sprintf(
                'Argument #2 passed to %s() must be an instance of %s, %s given.',
                __METHOD__,
                ClassMetadata::class,
                get_debug_type($metadata),
            ));
        }

        $this->reverseEngineerMappingFromDatabase();

        if (! isset($this->classToTableNames[$className])) {
            throw new InvalidArgumentException('Unknown class ' . $className);
        }

        $tableName = $this->classToTableNames[$className];

        $metadata->name          = $className;
        $metadata->table['name'] = $tableName;

        $this->buildIndexes($metadata);
        $this->buildFieldMappings($metadata);
        $this->buildToOneAssociationMappings($metadata);

        foreach ($this->manyToManyTables as $manyTable) {
            foreach ($manyTable->getForeignKeys() as $foreignKey) {
                // foreign key maps to the table of the current entity, many to many association probably exists
                if (! (strtolower($tableName) === strtolower(self::getReferencedTableName($foreignKey)))) {
                    continue;
                }

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Enumerate loadable classes with $driver->getAllClassNames() instead of your own list.
  2. Make derived names match your classes: call setNamespace('App\Entity') and/or setClassNameForTable($tableName, $className) before loading metadata.
  3. Check your schema asset filter configuration (FilterSchemaAssetsExpression / schema_assets_filter) — filtered tables never enter classToTableNames.

Example fix

// before
$driver = new DatabaseDriver($schemaManager);
$metadata = new ClassMetadata('App\Entity\User');
$driver->loadMetadataForClass('App\Entity\User', $metadata); // Unknown class App\Entity\User

// after
$driver = new DatabaseDriver($schemaManager);
$driver->setNamespace('App\\Entity');
$metadata = new ClassMetadata('App\Entity\User');
$driver->loadMetadataForClass('App\Entity\User', $metadata);
Defensive patterns

Strategy: validation

Validate before calling

$loadable = $driver->getAllClassNames(); // names derived from the actual schema
if (! in_array($className, $loadable, true)) {
    throw new InvalidArgumentException("{$className} cannot be reverse-engineered; available: " . implode(', ', $loadable));
}
$driver->loadMetadataForClass($className, $metadata);

Prevention

When it happens

Trigger: Calling loadMetadataForClass('App\Entity\User', ...) when the driver derived the class name 'User' (no namespace) from table 'user'; or loading a class whose table was excluded by a schema asset filter; or iterating your own entity list instead of the driver's getAllClassNames().

Common situations: Plugging DatabaseDriver into a standard ORM ClassMetadataFactory that walks your configured entity classes; forgetting setNamespace('App\Entity') / setClassNameForTable() when running orm:convert-mapping --from-database; tables hidden by dbname schema filters.

Related errors


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