{"record":{"id":"892e39cd36327d1d","repo":"phalcon/cphalcon","slug":"the-not-found-paths-must-be-an-array-or-string","errorCode":null,"errorMessage":"The not-found paths must be an array or string","messagePattern":"The not-found paths must be an array or string","errorType":"exception","errorClass":"Phalcon\\Mvc\\Router\\Exceptions\\InvalidNotFoundPaths","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Router.zep","lineNumber":1859,"sourceCode":"        for route in groupRoutes {\n            this->attach(route);\n        }\n\n        return this;\n    }\n\n    /**\n     * Set a group of paths to be returned when none of the defined routes are\n     * matched\n     *\n     * @param array|string|null paths\n     *\n     * @return static\n     */\n    public function notFound(var paths) -> <static>\n    {\n        if unlikely (typeof paths !== \"array\" && typeof paths !== \"string\") {\n            throw new InvalidNotFoundPaths();\n        }\n\n        let this->notFoundPaths = paths;\n\n        return this;\n    }\n\n    /**\n     * Set whether router must remove the extra slashes in the handled routes\n     *\n     * @param bool remove\n     *\n     * @return static\n     */\n    public function removeExtraSlashes( bool remove) -> <static>\n    {\n        let this->removeExtraSlashes = remove;\n","sourceCodeStart":1841,"sourceCodeEnd":1877,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Router.zep#L1841-L1877","documentation":"Router::notFound() stores the paths returned when nothing matches; it only accepts an array (['controller' => 'errors', 'action' => 'show404']) or a string in 'Controller::action' (optionally 'Module::Controller::action') short syntax. Any other type — including null, integers, booleans, or objects — throws InvalidNotFoundPaths. Note the docblock mentions null, but the implementation rejects it; there is no null-clearing path through this method.","triggerScenarios":"$router->notFound(null) attempting to clear the setting; $router->notFound(404); passing a Config object or stdClass as paths; passing a response object instead of route paths.","commonSituations":"Trying to unset a previously defined not-found route; passing an HTTP status code; feeding an object because the config was decoded without the associative flag.","solutions":["Pass a paths array: $router->notFound(['controller' => 'errors', 'action' => 'show404']);","Or the short string form: $router->notFound('Errors::show404');","To 'disable' behavior, route to a no-op controller/action instead of passing null","If the value comes from config, decode with json_decode(..., true) and confirm it is an array or string"],"exampleFix":"// before\n$router->notFound(null);\n$router->notFound(404);\n\n// after\n$router->notFound(\n    ['controller' => 'errors', 'action' => 'show404']\n);","handlingStrategy":"type-guard","validationCode":"// only pass array or 'Controller::action' strings to notFound()\n$notFound = $config['notFound'] ?? null;\n\nif ($notFound !== null && !is_array($notFound) && !is_string($notFound)) {\n    throw new InvalidArgumentException(\n        'notFound must be an array or Controller::action string, got ' . get_debug_type($notFound)\n    );\n}\n\nif ($notFound !== null) {\n    $router->notFound($notFound);\n}","typeGuard":"function isValidNotFoundPaths(mixed $paths): bool\n{\n    return is_array($paths) || is_string($paths);\n}","tryCatchPattern":"try {\n    $router->notFound($paths);\n} catch (\\Phalcon\\Mvc\\Router\\Exceptions\\InvalidNotFoundPaths $e) {\n    $logger->error('Invalid notFound paths: ' . get_debug_type($paths));\n    throw $e;\n}","preventionTips":["Use the canonical form: $router->notFound(['controller' => 'errors', 'action' => 'show404']);","Never pass null/int expecting to clear or signal 404 — null throws too","If notFound comes from config, decode with associative=true and type-check it"],"tags":["phalcon","router","not-found","route-paths","validation"],"backgroundTag":"invalid-route-configuration","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}