{"record":{"id":"b2b400d213e5d87e","repo":"Intervention/image","slug":"can-t-write-to-path-directory-dir-does","errorCode":null,"errorMessage":"Can't write to path. Directory \"' . $dir . '\" does not exist","messagePattern":"Can't write to path\\. Directory \"' \\. \\$dir \\. '\" does not exist","errorType":"exception","errorClass":"DirectoryNotFoundException","httpStatus":null,"severity":"error","filePath":"src/File.php","lineNumber":87,"sourceCode":"     * @throws FileNotWritableException\n     * @throws StreamException\n     */\n    public function save(string $path): void\n    {\n        if ($path === '') {\n            throw new InvalidArgumentException('Path must not be an empty string');\n        }\n\n        if (strlen($path) > PHP_MAXPATHLEN) {\n            throw new InvalidArgumentException(\n                \"Path is longer than the configured max. value of \" . PHP_MAXPATHLEN,\n            );\n        }\n\n        $dir = pathinfo($path, PATHINFO_DIRNAME);\n\n        if (!is_dir($dir)) {\n            throw new DirectoryNotFoundException(\n                'Can\\'t write to path. Directory \"' . $dir . '\" does not exist',\n            );\n        }\n\n        if (!is_writable($dir)) {\n            throw new FileNotWritableException(\n                'Can\\'t write to path. Directory \"' . $dir . '\" is not writable',\n            );\n        }\n\n        if (is_file($path) && !is_writable($path)) {\n            throw new FileNotWritableException(\n                \"Can't write to path. Existing file \" . $path . \" is not writable\",\n            );\n        }\n\n        // write data\n        $saved = file_put_contents($path, $this->toStream());","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/File.php#L69-L105","documentation":"Before writing, File::save() extracts the target directory with pathinfo($path, PATHINFO_DIRNAME) and verifies it exists with is_dir(). A missing directory throws DirectoryNotFoundException (a FilesystemException) - the library never creates directories for you.","triggerScenarios":"Calling $image->save('uploads/2026/08/photo.jpg') when 'uploads/2026/08' was never created; passing a relative path that resolves against an unexpected working directory (queue worker cwd vs web cwd) so is_dir() looks in the wrong place.","commonSituations":"Date-partitioned upload folders that only exist after the first write of that period; deploying without the storage directory; Docker/containers where the volume is mounted elsewhere; relative paths in artisan queue jobs.","solutions":["Create the directory beforehand: if (!is_dir($dir)) { mkdir($dir, 0775, true); }","Use absolute paths (e.g. base_path()/public_path() helpers) so the cwd cannot change resolution","Ensure the storage directory ships with your deployment or is created in a bootstrap step"],"exampleFix":"// before\n$image->save('uploads/' . date('Y/m') . '/photo.jpg'); // dir may not exist\n\n// after\n$dir = 'uploads/' . date('Y/m');\nif (!is_dir($dir)) {\n    mkdir($dir, 0775, true);\n}\n$image->save($dir . '/photo.jpg');","handlingStrategy":"validation","validationCode":"$dir = pathinfo($path, PATHINFO_DIRNAME);\nif (!is_dir($dir)) {\n    mkdir($dir, 0775, true);\n}\n$encoded->save($path);","typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\DirectoryNotFoundException;\n\ntry {\n    $image->save($path);\n} catch (DirectoryNotFoundException $e) {\n    mkdir(pathinfo($path, PATHINFO_DIRNAME), 0775, true);\n    $image->save($path);\n}","preventionTips":["Create date/partition directories eagerly with mkdir(..., recursive: true)","Use absolute paths so the process cwd cannot break resolution","Ensure storage directories exist in your deployment bootstrap"],"tags":["php","intervention-image","file","save","directory","filesystem"],"backgroundTag":"directory-not-found","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}