doctrine/orm · error · LogicException

No metadata for DQL alias: %s

Error message

No metadata for DQL alias: %s

What it means

TreeWalkerAdapter is Doctrine ORM's convenience base class for custom DQL tree walkers that visit the parsed AST while a query executes. getMetadataForDqlAlias() returns the ClassMetadata the parser stored in queryComponents for a DQL alias. This LogicException fires when a walker asks for an alias the parser never registered, meaning that alias is not a query component of the SELECT statement being walked.

Source

Thrown at src/Query/TreeWalkerAdapter.php:88

     * Retrieves the Query Instance responsible for the current walkers execution.
     */
    protected function _getQuery(): AbstractQuery
    {
        return $this->query;
    }

    /**
     * Retrieves the ParserResult.
     */
    protected function _getParserResult(): ParserResult
    {
        return $this->parserResult;
    }

    protected function getMetadataForDqlAlias(string $dqlAlias): ClassMetadata
    {
        return $this->queryComponents[$dqlAlias]['metadata']
            ?? throw new LogicException(sprintf('No metadata for DQL alias: %s', $dqlAlias));
    }
}

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Resolve aliases only from getQueryComponents() (e.g. iterate that array) instead of re-deriving them from AST nodes.
  2. Guard each lookup: if (! isset($this->getQueryComponents()[$dqlAlias]['metadata'])) skip or handle that node.
  3. Debug once by dumping array_keys($this->getQueryComponents()) next to the alias you pass.
  4. After upgrading Doctrine ORM majors, re-run tests that execute queries with your walker hint attached.

Example fix

// before - inside a custom TreeWalkerAdapter subclass
$metadata = $this->getMetadataForDqlAlias($alias); // LogicException when $alias came from a subquery

// after
$components = $this->getQueryComponents();
if (isset($components[$alias]['metadata'])) {
    $metadata = $this->getMetadataForDqlAlias($alias);
} else {
    return; // alias is not a component of this query: skip it
}
Defensive patterns

Strategy: validation

Validate before calling

// inside your TreeWalkerAdapter subclass, before resolving metadata
$components = $this->getQueryComponents();
if (! isset($components[$dqlAlias]['metadata'])) {
    return; // alias is not a component of the walked query: skip or log it
}
$metadata = $this->getMetadataForDqlAlias($dqlAlias);

Try / catch

LogicException signals a walker bug, not a runtime condition: catch \LogicException only to log the walker class, the DQL and the offending alias, then rethrow so the defect surfaces.

Prevention

When it happens

Trigger: A TreeWalkerAdapter subclass calls getMetadataForDqlAlias($alias) with an alias absent from $this->getQueryComponents(): an alias that only exists inside a subquery scope, a typo'd or case-mismatched alias, or an alias scraped from an AST node (e.g. a Join or SelectExpression) that is not a top-level component. It also fires when walker code mixes components from one query with the AST of another.

Common situations: Custom walkers for soft-delete or multi-tenant filters, Gedmo-style behavioral walkers reused on new query shapes, walker code copied between projects, and ORM major-version upgrades where the parser's AST or component keys changed.

Related errors


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