{"record":{"id":"ad8148038b7281da","repo":"phalcon/cphalcon","slug":"failed-to-write-router-cache-temp-file-tmppath","errorCode":null,"errorMessage":"Failed to write router cache temp file: {tmpPath}","messagePattern":"Failed to write router cache temp file: (.+?)","errorType":"exception","errorClass":"Phalcon\\Mvc\\Router\\Exception","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Router.zep","lineNumber":932,"sourceCode":"    }\n\n    /**\n     * File-shaped helper around buildDispatcherDump(). Writes the dump as\n     * a `<?php return [...];` file, atomically (temp + rename) so concurrent\n     * dumps don't corrupt the result.\n     *\n     * @throws \\Phalcon\\Mvc\\Router\\Exception\n     */\n    public function dumpDispatcher( string path) -> void\n    {\n        var dump, php, tmpPath;\n\n        let dump    = this->buildDispatcherDump();\n        let php     = \"<?php\\nreturn \" . var_export(dump, true) . \";\\n\";\n        let tmpPath = path . \".tmp.\" . (string) getmypid();\n\n        if this->phpFilePutContents(tmpPath, php) === false {\n            throw new Exception(\"Failed to write router cache temp file: \" . tmpPath);\n        }\n\n        if !rename(tmpPath, path) {\n            this->phpUnlink(tmpPath);\n            throw new Exception(\"Failed to commit router cache: \" . path);\n        }\n    }\n\n    /**\n     * File-shaped helper around loadDispatcherFromArray(). Includes the\n     * file (opcache-friendly) and forwards the return value.\n     *\n     * @throws \\Phalcon\\Mvc\\Router\\Exception\n     */\n    public function loadDispatcher( string path) -> void\n    {\n        var dump;\n","sourceCodeStart":914,"sourceCodeEnd":950,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Router.zep#L914-L950","documentation":"dumpDispatcher() writes the serialized router dump to a temp file next to the target (path . '.tmp.' . getmypid()) before atomically renaming it into place. If the low-level write fails (file_put_contents returns false), it throws with the concrete temp path. This is a filesystem-level failure: unwritable directory, missing directory, full disk, or path restrictions.","triggerScenarios":"Calling dumpDispatcher('/var/cache/app/routes.php') when /var/cache/app is not writable by the PHP user; passing a path whose parent directory does not exist; disk full on the cache volume; open_basedir restriction excluding the cache directory; read-only filesystem in a container.","commonSituations":"Deploy-time cache generation where the CI user owns the file but the web/PHP user cannot write (or vice versa); Docker images with read-only layers where the cache path was not mounted writable; shared hosting with restrictive open_basedir; disk exhaustion during cache rebuilds.","solutions":["Ensure the cache directory exists and is writable by the exact PHP/runtime user: mkdir -p + chown/chmod (e.g. chmod 775 with correct group)","Move the cache path to a directory designed for writes (var/cache of the app, /tmp-based dir), or mount it writable in containers","Check free disk space and quota on the cache volume","If open_basedir is active, verify the cache directory is inside an allowed path","Wrap the dump call in try/catch (Phalcon\\Mvc\\Router\\Exception) and log the tmpPath from the message for diagnosis"],"exampleFix":"// before\n$router->dumpDispatcher('/var/www/app/cache/routes.php'); // dir not writable -> throws\n\n// after: ensure the dir exists and is writable for the runtime user\n$dir = '/var/www/app/cache';\nif (!is_dir($dir)) { mkdir($dir, 0775, true); }\nif (!is_writable($dir)) { throw new RuntimeException(\"Cache dir not writable: {$dir}\"); }\n$router->dumpDispatcher($dir . '/routes.php');\n\n# shell equivalent\n# mkdir -p /var/www/app/cache && chown www-data:www-data /var/www/app/cache","handlingStrategy":"try-catch","validationCode":"// Pre-flight the cache target before dumping\n$dir = dirname($path);\nif (!is_dir($dir) || !is_writable($dir)) {\n    throw new RuntimeException(\"Router cache directory missing or not writable: {$dir}\");\n}\nif (disk_free_space($dir) < 1048576) {\n    throw new RuntimeException('Insufficient disk space for router cache');\n}\n$router->dumpDispatcher($path);","typeGuard":null,"tryCatchPattern":"try {\n    $router->dumpDispatcher($path);\n} catch (\\Phalcon\\Mvc\\Router\\Exception $e) {\n    // message contains the tmp path - log it and continue without cache\n    $logger->warning($e->getMessage());\n    $routesBuiltDynamically = true; // fall back to runtime-built routes\n}","preventionTips":["Provision cache directories (mkdir -p, correct ownership for the PHP user) as part of deploy","Mount cache volumes writable in containers; do not put them on read-only layers","Monitor free disk on cache volumes","Keep the cache path inside open_basedir-allowed directories"],"tags":["phalcon","router","caching","filesystem","permissions"],"backgroundTag":"file-write-permission-denied","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}