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
- Enumerate loadable classes with $driver->getAllClassNames() instead of your own list.
- Make derived names match your classes: call setNamespace('App\Entity') and/or setClassNameForTable($tableName, $className) before loading metadata.
- 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
- Always drive reverse engineering from getAllClassNames(), not your own entity list.
- Call setNamespace()/setClassNameForTable() up front so derived names match your classes.
- Audit schema asset filters before converting a database.
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
- Argument #2 passed to %s() must be an instance of %s, %s giv
- Table {tableName} has no primary key. Doctrine does not supp
- Uninitialized result set mapping.
- Unable to use access strategy type of [%s] without a Concurr
- Unrecognized access strategy type [%s]
AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21).
Data as JSON: /api/errors/fe64574c6cfaeccf.
Report an issue: GitHub.