{"record":{"id":"8f054edfdde9ab75","repo":"phalcon/cphalcon","slug":"group-route-entry-is-missing-paths","errorCode":null,"errorMessage":"Group route entry is missing 'paths'","messagePattern":"Group route entry is missing 'paths'","errorType":"exception","errorClass":"Phalcon\\Mvc\\Router\\Exceptions\\MissingGroupRouteKey","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Router.zep","lineNumber":2149,"sourceCode":"\n        if isset groupData[\"hostname\"] {\n            group->setHostname((string) groupData[\"hostname\"]);\n        }\n\n        if !fetch routes, groupData[\"routes\"] {\n            let routes = [];\n        }\n\n        if typeof routes !== \"array\" {\n            throw new GroupRoutesMustBeArray();\n        }\n\n        for routeData in routes {\n            if !fetch pattern, routeData[\"pattern\"] {\n                throw new MissingGroupRouteKey(\"pattern\");\n            }\n            if !fetch routePaths, routeData[\"paths\"] {\n                throw new MissingGroupRouteKey(\"paths\");\n            }\n\n            let method = \"\";\n            if isset routeData[\"method\"] && routeData[\"method\"] !== null {\n                let method = strtolower((string) routeData[\"method\"]);\n            }\n\n            switch method {\n                case \"\":\n                case \"connect\":\n                case \"delete\":\n                case \"get\":\n                case \"head\":\n                case \"options\":\n                case \"patch\":\n                case \"post\":\n                case \"purge\":\n                case \"put\":","sourceCodeStart":2131,"sourceCodeEnd":2167,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Router.zep#L2131-L2167","documentation":"Every group route definition must also carry a 'paths' key with the controller/action map for that route; its absence inside a group's routes entry throws MissingGroupRouteKey('paths').","triggerScenarios":"Group route entry with only {\"pattern\": \"/dashboard\"}; key named \"defaults\" or \"target\" instead of \"paths\"; empty-object entry from a template.","commonSituations":"Same as top-level missing 'paths' but within the groups section; assuming the group prefix supplies destinations; converting group code to config and forgetting the second argument's equivalent.","solutions":["Add \"paths\": {\"controller\": \"dashboard\", \"action\": \"index\"} to the entry","Use exactly the key 'paths'","Run a config validator before loadFromConfig that walks groups[].routes[] and checks both keys"],"exampleFix":"// before\n\"routes\": [\n    {\"pattern\": \"/dashboard\"}\n]\n\n// after\n\"routes\": [\n    {\n        \"pattern\": \"/dashboard\",\n        \"paths\": {\"controller\": \"dashboard\", \"action\": \"index\"}\n    }\n]","handlingStrategy":"validation","validationCode":"foreach ($config['groups'] ?? [] as $g => $group) {\n    foreach ($group['routes'] ?? [] as $i => $entry) {\n        if (!is_array($entry) || !array_key_exists('paths', $entry)) {\n            throw new InvalidArgumentException(\"groups[$g].routes[$i] is missing 'paths'\");\n        }\n    }\n}\n\n$router->loadFromConfig($config);","typeGuard":"function groupRouteEntryIsValid(mixed $entry): bool\n{\n    return is_array($entry)\n        && array_key_exists('pattern', $entry)\n        && array_key_exists('paths', $entry);\n}","tryCatchPattern":"try {\n    $router->loadFromConfig($config);\n} catch (\\Phalcon\\Mvc\\Router\\Exceptions\\MissingGroupRouteKey $e) {\n    $logger->error('Group route entry rejected: ' . $e->getMessage());\n    throw $e;\n}","preventionTips":["Every route entry inside a group needs its own destination map under 'paths'","The group 'prefix' is only a URI prefix — it never supplies controller/action","Lint nested group routes in CI the same way top-level routes are linted"],"tags":["phalcon","router","config","groups","route-definition","validation"],"backgroundTag":"invalid-route-configuration","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}