doctrine/orm · error · LengthException

Unexpected number of database columns.

Error message

Unexpected number of database columns.

What it means

In fetchVersionAndNotUpsertableValues(), after the re-select succeeds, array_combine() pairs the expected column keys with the returned row. An empty/false result means the number of columns the ORM expects (generated + version field columns it collected from fieldMappings) does not match what the query returned — an internal mapping invariant break, e.g., a versionField or generated attribute pointing at a field that is not a real mapped column.

Source

Thrown at src/Persisters/Entity/BasicEntityPersister.php:337

            . ' FROM ' . $tableName
            . ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';

        $flatId = $this->identifierFlattener->flattenIdentifier($versionedClass, $id);

        $values = $this->conn->fetchNumeric(
            $sql,
            array_values($flatId),
            $this->extractIdentifierTypes($id, $versionedClass),
        );

        if ($values === false) {
            throw new LengthException('Unexpected empty result for database query.');
        }

        $values = array_combine(array_keys($columnNames), $values);

        if (! $values) {
            throw new LengthException('Unexpected number of database columns.');
        }

        return $values;
    }

    /**
     * @param mixed[] $id
     *
     * @return list<ParameterType|int|string>
     * @phpstan-return list<ParameterType::*|ArrayParameterType::*|string>
     */
    final protected function extractIdentifierTypes(array $id, ClassMetadata $versionedClass): array
    {
        $types = [];

        foreach ($id as $field => $value) {
            $types = [...$types, ...PersisterHelper::inferParameterTypes($field, $value, $versionedClass, $this->em)];
        }

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Verify the #[Version] field actually exists as a mapped field column (name and mapping key match)
  2. Clear the metadata cache after changing versioned/generated fields (bin/console cache:clear or delete the query/metadata cache pool)
  3. Reproduce with logging enabled and check the generated SELECT column list against the table schema
Defensive patterns

Strategy: validation

Validate before calling

$meta = $em->getClassMetadata($entity::class);
if ($meta->isVersioned && ! isset($meta->fieldMappings[$meta->versionField])) {
    throw new RuntimeException('Version field is not a mapped field; fix metadata and clear cache.');
}

Prevention

When it happens

Trigger: ClassMetadata marked isVersioned with a versionField not present (or misnamed) in fieldMappings; a `generated` declaration on a field the persister did not select; SELECT list built empty so the combine produces nothing.

Common situations: Hand-edited/programmatic ClassMetadata where the version field name drifts from the real field mapping; metadata cached from an older entity definition after renaming a versioned or generated column without clearing the metadata cache.

Related errors


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