{"record":{"id":"4133d0f3b7cbec64","repo":"phalcon/cphalcon","slug":"extends-compilation-file-path-could-not-be-opene","errorCode":null,"errorMessage":"Extends compilation file {path} could not be opened","messagePattern":"Extends compilation file (.+?) could not be opened","errorType":"exception","errorClass":"CannotOpenCompiledFile","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/View/Engine/Volt/Compiler.zep","lineNumber":497,"sourceCode":"                 * Compare modification timestamps to check if the file\n                 * needs to be recompiled\n                 */\n                if compare_mtime(templatePath, compiledTemplatePath) {\n                    let compilation = this->compileFile(\n                        templatePath,\n                        compiledTemplatePath,\n                        extendsMode\n                    );\n                } else {\n                    if extendsMode {\n                        /**\n                         * In extends mode we read the file that must\n                         * contains a serialized array of blocks\n                         */\n                        let blocksCode = this->phpFileGetContents(compiledTemplatePath);\n\n                        if unlikely blocksCode === false {\n                            throw new CannotOpenCompiledFile(compiledTemplatePath);\n                        }\n\n                        /**\n                         * Unserialize the array blocks code\n                         */\n                        if blocksCode {\n                            let compilation = unserialize(blocksCode);\n                        } else {\n                            let compilation = [];\n                        }\n                    }\n                }\n            }\n        }\n\n        let this->compiledTemplatePath = compiledTemplatePath;\n\n        return compilation;","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/View/Engine/Volt/Compiler.zep#L479-L515","documentation":"Thrown in extends mode when Volt re-reads an already-compiled template (which must contain a serialized array of blocks) and file_get_contents() returns false. In extends mode Volt stores block definitions serialized in the compiled file; when that file exists (or stat check skipped) but cannot actually be read, the unserialization step is impossible and Volt aborts.","triggerScenarios":"An {% extends %} template is rendered, the compiled file exists at compiledTemplatePath, but the process cannot read it: wrong permissions, file removed between the exists-check and the read (race with cache clearing/deployment), or an open_basedir restriction that hides the path.","commonSituations":"Deployments that clear/regenerate the Volt cache while requests are in flight, compiled-cache directories written by root/CLI then read by the web server user, or open_basedir directives that cover the template dir but not the compiled dir.","solutions":["Check read permissions on the compiled file and directory for the web server user (ls -l + ps aux | grep php)","Clear the whole compiled Volt directory so templates regenerate atomically: rm -rf storage/cache/volt/*","If open_basedir is enabled, ensure the compiled path is inside an allowed base dir","Schedule cache clears during low traffic or use atomic directory swaps (build new dir, rename) to avoid read/write races"],"exampleFix":"// before\ncache/volt/ dir owned by root, app runs as www-data → read fails\n\n// after\nchown -R www-data:www-data storage/cache/volt\nchmod -R ug+rwX storage/cache/volt","handlingStrategy":"try-catch","validationCode":"$compiledFile = $volt->getCompiler()->getCompiledTemplatePath($template); // or compute as configured\nif ($compiledFile && !is_readable($compiledFile)) {\n    // regenerate before render\n    $volt->getCompiler()->compile($template);\n}","typeGuard":null,"tryCatchPattern":"try {\n    echo $volt->render('page.volt', $params);\n} catch (\\Phalcon\\Mvc\\View\\Engine\\Volt\\Exception $e) {\n    if (str_contains($e->getMessage(), 'could not be opened')) {\n        // cache file unreadable: purge and retry once\n        array_map('unlink', glob($cacheDir . '/*.php'));\n        echo $volt->render('page.volt', $params);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Keep the compiled cache owned by the PHP-FPM user","Clear the Volt cache with atomic directory swaps, never per-file unlinks during traffic","Ensure open_basedir includes the compiled directory"],"tags":["volt","template","extends","cache","permissions","filesystem"],"backgroundTag":"file-not-readable","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}