{"record":{"id":"08ee92ebca0e3b7a","repo":"rectorphp/rector","slug":"could-not-write-data-to-cache-file-s","errorCode":null,"errorMessage":"Could not write data to cache file %s.","messagePattern":"Could not write data to cache file (.+?)\\.","errorType":"exception","errorClass":"CachingException","httpStatus":null,"severity":"error","filePath":"src/Caching/ValueObject/Storage/FileCacheStorage.php","lineNumber":77,"sourceCode":"        $this->filesystem->mkdir($cacheFilePaths->getFirstDirectory());\n        $this->filesystem->mkdir($cacheFilePaths->getSecondDirectory());\n        $filePath = $cacheFilePaths->getFilePath();\n        $tmpPath = \\sprintf('%s/%s.tmp', $this->directory, Random::generate());\n        $errorBefore = \\error_get_last();\n        $exported = @\\var_export(new CacheItem($variableKey, $data), \\true);\n        $errorAfter = \\error_get_last();\n        if ($errorAfter !== null && $errorBefore !== $errorAfter) {\n            throw new CachingException(\\sprintf('Error occurred while saving item %s (%s) to cache: %s', $key, $variableKey, $errorAfter['message']));\n        }\n        // for performance reasons we don't use SmartFileSystem\n        FileSystem::write($tmpPath, \\sprintf(\"<?php declare(strict_types = 1);\\n\\nreturn %s;\", $exported), null);\n        $copySuccess = @\\copy($tmpPath, $filePath);\n        @\\unlink($tmpPath);\n        if ($copySuccess) {\n            return;\n        }\n        if (\\DIRECTORY_SEPARATOR === '/' || !\\file_exists($filePath)) {\n            throw new CachingException(\\sprintf('Could not write data to cache file %s.', $filePath));\n        }\n    }\n    public function clean(string $key): void\n    {\n        $cacheFilePaths = $this->getCacheFilePaths($key);\n        $this->processRemoveCacheFilePath($cacheFilePaths);\n        $this->processRemoveEmptyDirectory($cacheFilePaths->getSecondDirectory());\n        $this->processRemoveEmptyDirectory($cacheFilePaths->getFirstDirectory());\n    }\n    public function clear(): void\n    {\n        FileSystem::delete($this->directory);\n    }\n    private function processRemoveCacheFilePath(CacheFilePaths $cacheFilePaths): void\n    {\n        $filePath = $cacheFilePaths->getFilePath();\n        if (!$this->filesystem->exists($filePath)) {\n            return;","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/src/Caching/ValueObject/Storage/FileCacheStorage.php#L59-L95","documentation":"FileCacheStorage::save() writes each item to a temp file then @copy()s it into the two-level cache directory. If the copy fails and the platform is not Windows-with-existing-target, it throws CachingException naming the unreachable cache file. This is a filesystem-level failure: permissions, missing directory, or a full disk, almost never a Rector bug.","triggerScenarios":"The cache directory (default under sys temp or the configured cacheDirectory) is not writable by the current user: cache created by root then reused by a CI user, a read-only mount, disk quota exhausted, or a parallel job racing to delete directories (clean/clear-cache) while others save.","commonSituations":"Docker/CI where one stage runs rector as root and another as non-root; deploy pipelines running rector on read-only artifacts; /tmp cleanup daemons removing the temp file between write and copy.","solutions":["Fix ownership/permissions of the cache directory: rm -rf .cache/rector (or /tmp/rector) so the current user recreates it","Point the cache to a writable, per-user location: ->withCacheDirectory(__DIR__ . '/.rector-cache') or the cacheDirectory option","Check disk space and quota: df -h on the filesystem holding the cache dir","In CI, avoid concurrent rector runs sharing one cache directory (matrix jobs without distinct caches)"],"exampleFix":"# before: cache dir owned by root, run as ci user\nvendor/bin/rector process src  # CachingException: Could not write data to cache file\n\n# after: give the run its own writable cache\nrm -rf .cache/rector\nvendor/bin/rector process src --cache-directory .rector-cache-ci","handlingStrategy":"fallback","validationCode":"// preflight in CI: verify the cache directory is writable by this user\n$cacheDir = sys_get_temp_dir() . '/rector'; // or your configured cacheDirectory\nif (is_dir($cacheDir) && ! is_writable($cacheDir)) {\n    fwrite(STDERR, \"Cache dir not writable: {$cacheDir}\\n\");\n    exit(1);\n}","typeGuard":null,"tryCatchPattern":"catch \\Rector\\Caching\\Exception\\CachingException, inspect the path in the message, fix permissions/chown, then retry the run; do not ignore -- a failed cache write silently costs full re-analysis on every run.","preventionTips":["Run rector under a single consistent user in CI/Docker (avoid root-then-non-root on the same cache dir)","Give each CI job/matrix leg its own cache directory","Monitor free disk space on the filesystem hosting the cache directory"],"tags":["php","rector","cache","filesystem","permissions","disk-full"],"backgroundTag":"cache-write-permission-denied","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}