Intervention/image · error · DirectoryNotFoundException
Can't write to path. Directory "' . $dir . '" does not exist
Error message
Can't write to path. Directory "' . $dir . '" does not exist
What it means
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.
Source
Thrown at src/File.php:87
* @throws FileNotWritableException
* @throws StreamException
*/
public function save(string $path): void
{
if ($path === '') {
throw new InvalidArgumentException('Path must not be an empty string');
}
if (strlen($path) > PHP_MAXPATHLEN) {
throw new InvalidArgumentException(
"Path is longer than the configured max. value of " . PHP_MAXPATHLEN,
);
}
$dir = pathinfo($path, PATHINFO_DIRNAME);
if (!is_dir($dir)) {
throw new DirectoryNotFoundException(
'Can\'t write to path. Directory "' . $dir . '" does not exist',
);
}
if (!is_writable($dir)) {
throw new FileNotWritableException(
'Can\'t write to path. Directory "' . $dir . '" is not writable',
);
}
if (is_file($path) && !is_writable($path)) {
throw new FileNotWritableException(
"Can't write to path. Existing file " . $path . " is not writable",
);
}
// write data
$saved = file_put_contents($path, $this->toStream());View on GitHub (pinned to 5598b9e397)
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
Example fix
// before
$image->save('uploads/' . date('Y/m') . '/photo.jpg'); // dir may not exist
// after
$dir = 'uploads/' . date('Y/m');
if (!is_dir($dir)) {
mkdir($dir, 0775, true);
}
$image->save($dir . '/photo.jpg'); Defensive patterns
Strategy: validation
Validate before calling
$dir = pathinfo($path, PATHINFO_DIRNAME);
if (!is_dir($dir)) {
mkdir($dir, 0775, true);
}
$encoded->save($path); Try / catch
use Intervention\Image\Exceptions\DirectoryNotFoundException;
try {
$image->save($path);
} catch (DirectoryNotFoundException $e) {
mkdir(pathinfo($path, PATHINFO_DIRNAME), 0775, true);
$image->save($path);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Can't write to path. Directory "' . $dir . '" is not writabl
- Can't write to path. Existing file " . $path . " is not writ
- Failed to write file to path " . $path
- Failed to open file from path "' . $path . '"
- Path must not be an empty string
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/b2b400d213e5d87e.
Report an issue: GitHub.