sebastianbergmann/phpunit · error · DirectoryDoesNotExistException
Directory "%s" does not exist and could not be created
Error message
Directory "%s" does not exist and could not be created
What it means
TestIndex::persist() writes its index to $this->indexFilename and first asks Filesystem::createDirectory() to create the file's parent directory; when that returns false, DirectoryDoesNotExistException('Directory "%s" does not exist and could not be created') is thrown. So the directory of the configured index/cache location neither exists nor could be created by the PHP process.
Source
Thrown at src/Runner/TestIndex/TestIndex.php:195
continue;
}
$this->entries[$file] = $entry;
}
}
/**
* Entries that were not recorded during this run are written back
* unchanged: a run that skipped a file did not learn anything about it and
* must not cause what is known about it to be forgotten. Entries for files
* that no longer exist are dropped.
*
* @throws Exception
*/
public function persist(): void
{
if (!Filesystem::createDirectory(dirname($this->indexFilename))) {
throw new DirectoryDoesNotExistException(dirname($this->indexFilename));
}
/*
* The group names are collected in a list of their own, and not as the
* keys of the map that assigns a position to each of them: a group name
* such as "6546" would become an integer key, and would then be written
* as an integer and no longer be readable as a group name.
*/
$groupNames = [];
$groupPositions = [];
$entries = [];
foreach ($this->entries as $file => $entry) {
if (!is_file($file)) {
continue;
}
$groups = [];View on GitHub (pinned to f123cdb2a2)
Solutions
- Create the directory manually and give the PHP process write permission: mkdir -p path/to/dir && chown $(whoami) path/to/dir.
- Point the index/cache location to a writable directory in your configuration.
- Check open_basedir and read-only mounts (containers) covering the configured path.
Example fix
# before phpunit # persist() fails: Directory "/build/.phpunit" does not exist and could not be created # after mkdir -p /build/.phpunit && chmod u+w /build/.phpunit phpunit
Defensive patterns
Strategy: validation
Validate before calling
// before persisting the test index, ensure the target directory is writable
$dir = dirname($indexFilename);
if (!is_dir($dir) && !@mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new RuntimeException("Cannot create index directory {$dir}; check permissions/open_basedir");
}
if (!is_writable($dir)) {
throw new RuntimeException("Index directory {$dir} is not writable");
} Prevention
- Configure the index/cache path to a directory guaranteed writable in CI (e.g. a workspace dir), not a read-only layer.
- Provision the directory in the container/CI job definition before running PHPUnit.
- Run the test process as a user with write access to the configured path.
When it happens
Trigger: Calling persist() when the index file's parent directory does not exist and cannot be created: the path is outside open_basedir, the filesystem is read-only, or the process lacks write permission on the parent.
Common situations: Running in containers/CI with a read-only or non-writable volume mounted at the cache location; a configured cache directory path with a typo; open_basedir restrictions; running as a user without write access to the project root.
Related errors
- Directory "%s" does not exist and could not be created
- Directory "%s" does not exist and could not be created
- Cannot write baseline to "%s".
- The path "%s" specified for the --log-events-text option cou
- Unable to write temporary file
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/6bbbac44fdb0d2cf.
Report an issue: GitHub.