{"record":{"id":"55fd91b991b2de79","repo":"phalcon/cphalcon","slug":"cannot-read-annotation-data","errorCode":null,"errorMessage":"Cannot read annotation data","messagePattern":"Cannot read annotation data","errorType":"exception","errorClass":"Phalcon\\Annotations\\Exceptions\\CannotReadAnnotationData","httpStatus":null,"severity":"error","filePath":"phalcon/Annotations/Adapter/Stream.zep","lineNumber":94,"sourceCode":"\n        if unlikely empty contents {\n            return false;\n        }\n\n        globals_set(\"warning.enable\", false);\n        set_error_handler(\n            function (number, message, file, line) {\n                globals_set(\"warning.enable\", true);\n            },\n            E_WARNING\n        );\n\n        let contents = unserialize(contents);\n\n        restore_error_handler();\n\n        if unlikely globals_get(\"warning.enable\") {\n            throw new CannotReadAnnotationData();\n        }\n\n        return contents;\n    }\n\n    /**\n     * Writes parsed annotations to files\n     */\n    public function write( string key, <Reflection> data) -> void\n    {\n        var code;\n        string path;\n\n        /**\n         * Paths must be normalized before be used as keys\n         */\n        let path = this->annotationsDir . prepare_virtual_path(key, \"_\") . \".php\",\n            code = serialize(data);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Annotations/Adapter/Stream.zep#L76-L112","documentation":"The Annotations Stream adapter caches parsed annotations as serialized Reflection objects on disk. On read, unserialize() runs under a temporary error handler; if unserialize emits any E_WARNING (bad data, wrong offset, truncated payload), the handler sets a flag and the adapter throws CannotReadAnnotationData instead of returning garbage. It means the cache file under annotationsDir exists but its contents cannot be unserialized.","triggerScenarios":"`$annotations->get($class)` / `$annotations->read($key)` on a class whose cached file in annotationsDir is corrupt or incompatible: truncated writes (disk full, killed process), cache files produced by an older Phalcon/PHP release, or files edited by hand.","commonSituations":"Deploying a new Phalcon version over old cache files; concurrent workers writing the same cache key; a disk-full event truncating serialized payloads; copying caches between environments built by different PHP versions.","solutions":["Delete everything under the configured annotationsDir so annotations are re-parsed and re-cached on the next request","If it recurs, check the directory for concurrent writers and give each deployment its own cache prefix/directory","Verify the annotationsDir is writable and not subject to open_basedir restrictions that could corrupt write behavior","As a stopgap, switch to the Memory adapter (no disk cache) while you fix the underlying serialization issue"],"exampleFix":"// before: stale/corrupt cache triggers CannotReadAnnotationData on first get()\n$annotations = new \\Phalcon\\Annotations\\Adapter\\Stream(['annotationsDir' => '/app/storage/annotations/']);\n$reflector = $annotations->get(Invoices::class);\n// after: purge the cache once after upgrading, then use normally\nforeach (glob('/app/storage/annotations/*.php') ?: [] as $file) {\n    unlink($file);\n}\n$reflector = $annotations->get(Invoices::class);","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $reflector = $annotations->get(Invoices::class);\n} catch (\\Phalcon\\Annotations\\Exceptions\\CannotReadAnnotationData $e) {\n    // cache entry corrupt: purge and regenerate once, then retry\n    array_map('unlink', glob($annotationsDir . '*.php') ?: []);\n    $reflector = $annotations->get(Invoices::class);\n}","preventionTips":["Clear the annotations cache as part of every Phalcon/PHP upgrade deployment step","Give each deployment its own cache directory to avoid cross-version file mixing","Monitor disk-full events and concurrent writers on the cache directory"],"tags":["annotations","cache","unserialize","stream-adapter"],"backgroundTag":"corrupted-cache-file","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}