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

  1. Create the directory manually and give the PHP process write permission: mkdir -p path/to/dir && chown $(whoami) path/to/dir.
  2. Point the index/cache location to a writable directory in your configuration.
  3. 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

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


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/6bbbac44fdb0d2cf. Report an issue: GitHub.