{"record":{"id":"a766736f2ffa32a1","repo":"phalcon/cphalcon","slug":"no-route-matched-the-request","errorCode":null,"errorMessage":"No route matched the request.","messagePattern":"No route matched the request\\.","errorType":"exception","errorClass":"Phalcon\\ADR\\Exceptions\\RouteNotFound","httpStatus":404,"severity":"error","filePath":"phalcon/ADR/Application.zep","lineNumber":163,"sourceCode":"\n        if !empty this->middlewareMap {\n            router->setMiddlewareMap(this->middlewareMap);\n        }\n\n        if this->actionDirectory !== \"\" {\n            router->setActionDirectory(this->actionDirectory);\n        }\n\n        if this->wordSeparator !== \"\" {\n            router->setWordSeparator(this->wordSeparator);\n        }\n\n        events->fire(Event::APPLICATION_BEFORE_HANDLE, this, request);\n\n        try {\n            let match = router->match(request);\n            if match === null {\n                throw new RouteNotFound();\n            }\n\n            let attributes = this->container\n                ->get(AttributeFilterInterface::class)\n                ->filter(match->getAction(), match->getAttributes());\n\n            for key, value in attributes {\n                request->getAttributes()->set(key, value);\n            }\n\n            let response = dispatcher->dispatch(\n                match->getAction(),\n                request,\n                match->getMiddleware()\n            );\n        } catch \\Throwable, exception {\n            try {\n                let response = this->container->get(ErrorResponder::class)->handle(","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/ADR/Application.zep#L145-L181","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\n$builder = $modelsManager\n    ->createBuilder()\n    ->from(Orders::class)\n    ->having('COUNT(customerId) > 5');\n\n$paginator = new QueryBuilder(\n    [\n        'builder' => $builder,\n        'limit'   => 20,\n    ]\n); // paginate() throws MissingColumnsForHaving\n\n// after\n$paginator = new QueryBuilder(\n    [\n        'builder' => $builder,\n        'limit'   => 20,\n        'columns' => 'customerId', // feeds the count subquery only\n    ]\n);","handlingStrategy":"validation","validationCode":"// Before paginate(): does this query need the count-subquery path?\n$hasHaving = !empty($builder->getHaving());\n$hasGroup  = !empty($builder->getGroupBy());\nif ($hasHaving && !$hasGroup && empty($columns)) {\n    throw new \\InvalidArgumentException(\n        'HAVING without GROUP BY requires paginator option [\\'columns\\'\\'\n        . ' => \\'<column list for the counting subquery\\']'\n    );\n}\n$paginator = new \\Phalcon\\Paginator\\Adapter\\QueryBuilder(\n    [\n        'builder' => $builder,\n        'limit'   => 20,\n        'columns' => $columns ?? 'id',\n    ]\n);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["paginator","querybuilder","having","sql","phalcon"],"backgroundTag":"pagination-total-count","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}