phalcon/cphalcon · error · Phalcon\ADR\Exceptions\RouteNotFound
No route matched the request.
Error message
No route matched the request.
What it means
Thrown by Phalcon\Paginator\Adapter\QueryBuilder::paginate() (MissingColumnsForHaving) when the paginated builder has a HAVING clause but no GROUP BY and the paginator was not given a 'columns' option. Without GROUP BY the adapter cannot rewrite the query to COUNT(*), because the HAVING filter applies to computed rows; it needs your column list to build the counting subquery. The 'columns' option is consumed only by this total-count rewrite, not by the rows you display.
Source
Thrown at phalcon/ADR/Application.zep:163
if !empty this->middlewareMap {
router->setMiddlewareMap(this->middlewareMap);
}
if this->actionDirectory !== "" {
router->setActionDirectory(this->actionDirectory);
}
if this->wordSeparator !== "" {
router->setWordSeparator(this->wordSeparator);
}
events->fire(Event::APPLICATION_BEFORE_HANDLE, this, request);
try {
let match = router->match(request);
if match === null {
throw new RouteNotFound();
}
let attributes = this->container
->get(AttributeFilterInterface::class)
->filter(match->getAction(), match->getAttributes());
for key, value in attributes {
request->getAttributes()->set(key, value);
}
let response = dispatcher->dispatch(
match->getAction(),
request,
match->getMiddleware()
);
} catch \Throwable, exception {
try {
let response = this->container->get(ErrorResponder::class)->handle(View on GitHub (pinned to b7419de9cd)
Solutions
- Pass the 'columns' option to the paginator config, e.g. new QueryBuilder(['builder' => $builder, 'limit' => 20, 'columns' => 'id']) — supply the column list the counting subquery should select.
- If the query is genuinely aggregate, add a groupBy() to the builder so the adapter takes the GROUP BY counting path instead.
- If neither fits, compute the total yourself with an explicit COUNT query and paginate with a different adapter (e.g. NativeArray with a manual repository).
Example fix
// before
$builder = $modelsManager
->createBuilder()
->from(Orders::class)
->having('COUNT(customerId) > 5');
$paginator = new QueryBuilder(
[
'builder' => $builder,
'limit' => 20,
]
); // paginate() throws MissingColumnsForHaving
// after
$paginator = new QueryBuilder(
[
'builder' => $builder,
'limit' => 20,
'columns' => 'customerId', // feeds the count subquery only
]
); Defensive patterns
Strategy: validation
Validate before calling
// Before paginate(): does this query need the count-subquery path?
$hasHaving = !empty($builder->getHaving());
$hasGroup = !empty($builder->getGroupBy());
if ($hasHaving && !$hasGroup && empty($columns)) {
throw new \InvalidArgumentException(
'HAVING without GROUP BY requires paginator option [\'columns\'\'
. ' => \'<column list for the counting subquery\']'
);
}
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder(
[
'builder' => $builder,
'limit' => 20,
'columns' => $columns ?? 'id',
]
); Prevention
- Treat 'columns' as mandatory whenever you paginate a builder with having() and no groupBy().
- Wrap paginator construction in one factory method that validates limit/builder/columns together.
- Add a unit test for every paginated reporting query asserting paginate() returns a repository.
When it happens
Trigger: new QueryBuilder(['builder' => $builder, 'limit' => 20]) followed by paginate() where $builder->having('COUNT(*) > 2') (or any having()) is set, no groupBy() is set, and no 'columns' key exists in the paginator config.
Common situations: Paginating aggregate/report queries (e.g. 'users with more than N orders') in an admin grid; removing a GROUP BY during refactoring while keeping the HAVING; upgrading from a paginator version that silently miscounted these queries.
Related errors
- Class '{className}' is not an ADR Action.
- No action directory set; call setActionDirectory().
- Matched parameter was not found in parameters list
- Cannot prepare statement
- The index 'tables' is required in the definition array
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/a766736f2ffa32a1.
Report an issue: GitHub.