{"record":{"id":"b69188c2b0d1ead6","repo":"phalcon/cphalcon","slug":"group-route-entry-is-missing-pattern","errorCode":null,"errorMessage":"Group route entry is missing 'pattern'","messagePattern":"Group route entry is missing 'pattern'","errorType":"exception","errorClass":"Phalcon\\Mvc\\Router\\Exceptions\\MissingGroupRouteKey","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Router.zep","lineNumber":2146,"sourceCode":"        if isset groupData[\"prefix\"] {\n            group->setPrefix((string) groupData[\"prefix\"]);\n        }\n\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\":","sourceCodeStart":2128,"sourceCodeEnd":2164,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Router.zep#L2128-L2164","documentation":"Inside every group route definition (config['groups'][*]['routes'][*]), the 'pattern' key is mandatory. When mountGroupFromConfig iterates a group's routes and cannot fetch routeData['pattern'], it throws MissingGroupRouteKey('pattern') naming the key.","triggerScenarios":"A group route entry {\"paths\": {...}} without \"pattern\"; key spelled \"match\" or \"path\"; pattern left out while converting inline group->add() calls to config.","commonSituations":"Porting programmatic groups into config files and dropping the first constructor argument's equivalent; inconsistent generators; partial copy-paste between route entries.","solutions":["Add \"pattern\" to every group route entry: {\"pattern\": \"/dashboard\", \"paths\": {...}}","Use exactly the key 'pattern'","Validate nested group routes up front (see validation snippet) to catch the entry index"],"exampleFix":"// before\n\"groups\": [\n    {\n        \"prefix\": \"/admin\",\n        \"routes\": [\n            {\"paths\": {\"controller\": \"dashboard\", \"action\": \"index\"}}\n        ]\n    }\n]\n\n// after\n\"groups\": [\n    {\n        \"prefix\": \"/admin\",\n        \"routes\": [\n            {\n                \"pattern\": \"/dashboard\",\n                \"paths\": {\"controller\": \"dashboard\", \"action\": \"index\"}\n            }\n        ]\n    }\n]","handlingStrategy":"validation","validationCode":"// walk groups and verify each nested route entry has pattern + paths\nforeach ($config['groups'] ?? [] as $g => $group) {\n    foreach ($group['routes'] ?? [] as $i => $entry) {\n        if (!is_array($entry) || !isset($entry['pattern'], $entry['paths'])) {\n            throw new InvalidArgumentException(\n                \"groups[$g].routes[$i] must define both 'pattern' and 'paths'\"\n            );\n        }\n    }\n}\n\n$router->loadFromConfig($config);","typeGuard":"function groupRouteEntryIsValid(mixed $entry): bool\n{\n    return is_array($entry) && isset($entry['pattern'], $entry['paths']);\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":["When porting group->add($pattern, $paths) calls to config, map argument 1 to 'pattern' and argument 2 to 'paths' every time","Add a config schema test that walks groups[].routes[] for both required keys","Keep group route entries structurally identical to top-level entries to reduce drift"],"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"}