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
DefaultTestRunHistory::writeToFile() (reached from persist()/persistAndPrune()) stores the test run history file and, like the test index, first tries Filesystem::createDirectory() on dirname($this->filename); when creation fails it throws DirectoryDoesNotExistException('Directory "%s" does not exist and could not be created'). The parent directory of the run-history file neither exists nor is creatable by the PHP process.
Source
Thrown at src/Runner/TestRunHistory/DefaultTestRunHistory.php:182
/**
* Persists only the entries that were touched since load(). This drops
* the entries of tests that no longer exist and must only be used when
* the current test run executed every test that exists.
*
* @throws Exception
*/
public function persistAndPrune(): void
{
$this->writeToFile(true);
}
/**
* @throws Exception
*/
private function writeToFile(bool $prune): void
{
if (!Filesystem::createDirectory(dirname($this->filename))) {
throw new DirectoryDoesNotExistException(dirname($this->filename));
}
$handle = fopen($this->filename, 'c+');
if ($handle === false) {
// @codeCoverageIgnoreStart
return;
// @codeCoverageIgnoreEnd
}
flock($handle, LOCK_EX);
if ($prune) {
$defects = [];
foreach ($this->defects as $id => $status) {
if (isset($this->changedDefects[$id])) {
$defects[$id] = $status;View on GitHub (pinned to f123cdb2a2)
Solutions
- Create the directory beforehand and make it writable by the PHP process: mkdir -p path/to/dir.
- Configure the run history/cache location to a writable directory.
- Verify open_basedir settings and that the volume is mounted read-write in containers.
Example fix
# before phpunit # writeToFile() fails: Directory "/var/cache/phpunit" does not exist and could not be created # after mkdir -p /var/cache/phpunit phpunit
Defensive patterns
Strategy: validation
Validate before calling
// before persisting the run history, ensure its directory is writable
$dir = dirname($historyFilename);
if (!is_dir($dir) && !@mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new RuntimeException("Cannot create run-history directory {$dir}");
}
if (!is_writable($dir)) {
throw new RuntimeException("Run-history directory {$dir} is not writable");
} Prevention
- Point the run-history/cache location at a writable volume in containers.
- Check open_basedir when hardening php.ini so the history path stays reachable.
- Verify with is_writable() during environment smoke tests in CI.
When it happens
Trigger: Persisting the run history when its target directory is missing and cannot be created — read-only filesystem, missing write permission, or a path excluded by open_basedir.
Common situations: CI containers with read-only project mounts; a run-history path pointing outside the sandbox; permission changes between runs (running as different users).
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/fe49aa0fbb3ff352.
Report an issue: GitHub.