doctrine/orm · error · RuntimeException
Cannot count query which selects two FROM components, cannot
Error message
Cannot count query which selects two FROM components, cannot make distinction
What it means
WhereInWalker is the Paginator's tree walker that rewrites the paginated query into 'SELECT ... WHERE root.id IN (:dpid)'. It derives the root entity from the first FROM declaration; with two or more identification variable declarations there is no single root to filter on, so it refuses. The identical guard exists in LimitSubqueryOutputWalker::getSQLIdentifier (line 517), so switching to output walkers does not make a multi-root query paginable - the query must have one root.
Source
Thrown at src/Tools/Pagination/WhereInWalker.php:51
class WhereInWalker extends TreeWalkerAdapter
{
/**
* ID Count hint name.
*/
public const HINT_PAGINATOR_HAS_IDS = 'doctrine.paginator_has_ids';
/**
* Primary key alias for query.
*/
public const PAGINATOR_ID_ALIAS = 'dpid';
public function walkSelectStatement(SelectStatement $selectStatement): void
{
// Get the root entity and alias from the AST fromClause
$from = $selectStatement->fromClause->identificationVariableDeclarations;
if (count($from) > 1) {
throw new RuntimeException('Cannot count query which selects two FROM components, cannot make distinction');
}
$fromRoot = reset($from);
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
$rootClass = $this->getMetadataForDqlAlias($rootAlias);
$identifierFieldName = $rootClass->getSingleIdentifierFieldName();
$pathType = PathExpression::TYPE_STATE_FIELD;
if (isset($rootClass->associationMappings[$identifierFieldName])) {
$pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
}
$pathExpression = new PathExpression(PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $rootAlias, $identifierFieldName);
$pathExpression->type = $pathType;
$hasIds = $this->_getQuery()->getHint(self::HINT_PAGINATOR_HAS_IDS);
if ($hasIds) {View on GitHub (pinned to d9b9ff7301)
Solutions
- Reduce the query to a single FROM component by converting the second root into an explicit JOIN ('JOIN App\Entity\Address a WITH a.user = u') or a WHERE EXISTS subquery.
- Paginate the primary entity only, then load the secondary data for the page in a follow-up query.
- Compute the total with a dedicated single-root COUNT query and fetch pages manually via setFirstResult/setMaxResults.
Example fix
// before $dql = 'SELECT u, a FROM App\Entity\User u, App\Entity\Address a WHERE u.id = a.userId'; count(new Paginator($em->createQuery($dql))); // RuntimeException // after $dql = 'SELECT u FROM App\Entity\User u JOIN u.address a'; count(new Paginator($em->createQuery($dql)));
Defensive patterns
Strategy: validation
Validate before calling
// Both count() and getIterator() require a single root; check before using Paginator
$ast = $query->getAST();
$fromCount = count($ast->fromClause->identificationVariableDeclarations);
if ($fromCount !== 1) {
throw new InvalidArgumentException(sprintf('Cannot paginate a query with %d FROM components', $fromCount));
} Prevention
- Write pagination DQL with one root plus explicit JOINs from day one
- Add a repository-level guard/CI check rejecting theta-style FROM in paginated queries
- Remember output walkers throw the same error - the only fix is rewriting the query
When it happens
Trigger: Paginator count() or iteration (tree-walker path: setUseOutputWalkers(false) or a query-level custom output walker hint) over a DQL with more than one FROM component such as 'SELECT u, a FROM App\Entity\User u, App\Entity\Address a WHERE ...'. In output-walker mode the same multi-root query throws the identical message from LimitSubqueryOutputWalker.
Common situations: Theta-style comma joins left over from legacy DQL; repository queries cross-joining an unrelated entity for filtering; attempts to paginate queries that select two entity types at once.
Related errors
- Can only process queries that select only one FROM component
- Not all identifier properties can be found in the ResultSetM
- Paginating an entity with foreign key as identifier only wor
- Cannot select distinct identifiers from query with LIMIT and
- {argAlias} does not exist
AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21).
Data as JSON: /api/errors/266249181674e579.
Report an issue: GitHub.