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

  1. 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.
  2. If the query is genuinely aggregate, add a groupBy() to the builder so the adapter takes the GROUP BY counting path instead.
  3. 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

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


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/a766736f2ffa32a1. Report an issue: GitHub.