{"record":{"id":"120fe83da1f15b02","repo":"phalcon/cphalcon","slug":"route-config-entry-is-missing-paths","errorCode":null,"errorMessage":"Route config entry is missing 'paths'","messagePattern":"Route config entry is missing 'paths'","errorType":"exception","errorClass":"Phalcon\\Mvc\\Router\\Exceptions\\MissingRouteConfigKey","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Router.zep","lineNumber":2065,"sourceCode":"    }\n\n    /**\n     * Adds a single route from a config array entry. Used by loadFromConfig.\n     *\n     * @param array routeData\n     *\n     * @return void\n     */\n    protected function addRouteFromConfig(array routeData) -> void\n    {\n        var method, methodClass, pattern, paths, route;\n\n        if !fetch pattern, routeData[\"pattern\"] {\n            throw new MissingRouteConfigKey(\"pattern\");\n        }\n\n        if !fetch paths, routeData[\"paths\"] {\n            throw new MissingRouteConfigKey(\"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":2047,"sourceCodeEnd":2083,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Router.zep#L2047-L2083","documentation":"Companion to the 'pattern' check: every entry in config['routes'] must also contain a 'paths' key (the controller/action/parameter map applied when the pattern matches). MissingRouteConfigKey('paths') is thrown when routeData['paths'] cannot be fetched.","triggerScenarios":"{\"pattern\": \"/about\"} with no \"paths\"; key written as \"path\", \"defaults\", or \"target\"; an intentionally empty destinations object written as a string or omitted entirely.","commonSituations":"Assuming a pattern-only route defaults somewhere; refactoring that dropped the paths element; differing conventions between projects (paths vs defaults naming).","solutions":["Add an explicit paths map, even if minimal: {\"pattern\": \"/about\", \"paths\": {\"controller\": \"about\", \"action\": \"index\"}}","Use exactly the key 'paths' (lowercase, plural)","Pre-validate entries for both required keys (see validation snippet)"],"exampleFix":"// before\n{\n    \"routes\": [\n        {\"pattern\": \"/about\"}\n    ]\n}\n\n// after\n{\n    \"routes\": [\n        {\n            \"pattern\": \"/about\",\n            \"paths\": {\"controller\": \"about\", \"action\": \"index\"}\n        }\n    ]\n}","handlingStrategy":"validation","validationCode":"foreach ($config['routes'] ?? [] as $i => $entry) {\n    if (!is_array($entry) || !isset($entry['pattern'], $entry['paths'])) {\n        throw new InvalidArgumentException(\n            \"routes[$i] must define both 'pattern' and 'paths'\"\n        );\n    }\n}\n\n$router->loadFromConfig($config);","typeGuard":"function routeEntryIsValid(mixed $entry): bool\n{\n    return is_array($entry)\n        && isset($entry['pattern'], $entry['paths']);\n}","tryCatchPattern":"try {\n    $router->loadFromConfig($config);\n} catch (\\Phalcon\\Mvc\\Router\\Exceptions\\MissingRouteConfigKey $e) {\n    $logger->error('Route config entry rejected: ' . $e->getMessage());\n    throw $e;\n}","preventionTips":["A pattern alone routes nowhere in this router — always pair it with a paths map","Keep a shared example route entry in your docs so copy-paste carries both keys","Validate route entries in a config loader test that runs on every build"],"tags":["phalcon","router","config","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"}