sebastianbergmann/phpunit · error · CannotWriteBaselineException
Cannot write baseline to "%s".
Error message
Cannot write baseline to "%s".
What it means
A baseline write was requested (--generate-baseline, or Writer::write() called from a run) but the directory that would contain the file does not exist: realpath(dirname($baselineFile)) failed or the result is not a directory. Only the parent directory is verified — the file itself is then written with file_put_contents.
Source
Thrown at src/Runner/Baseline/Writer.php:36
/**
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
*
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final readonly class Writer
{
/**
* @param non-empty-string $baselineFile
*
* @throws CannotWriteBaselineException
*/
public function write(string $baselineFile, Baseline $baseline): void
{
$normalizedBaselineFile = realpath(dirname($baselineFile));
if ($normalizedBaselineFile === false || !is_dir($normalizedBaselineFile)) {
throw new CannotWriteBaselineException(sprintf('Cannot write baseline to "%s".', $baselineFile));
}
$pathCalculator = new RelativePathCalculator($normalizedBaselineFile);
$writer = new XMLWriter;
$writer->openMemory();
$writer->setIndent(true);
$writer->startDocument();
$writer->startElement('files');
$writer->writeAttribute('version', (string) Baseline::VERSION);
foreach ($baseline->groupedByFileAndLine() as $file => $lines) {
$writer->startElement('file');
$writer->writeAttribute('path', $pathCalculator->calculate($file));
foreach ($lines as $line => $issues) {View on GitHub (pinned to f123cdb2a2)
Solutions
- Create the parent directory first: mkdir -p build (or commit a .gitkeep inside it).
- Fix the path passed to --generate-baseline so every directory component exists.
- If calling Writer::write() programmatically, ensure dirname($baselineFile) passes realpath() and is_dir() first.
Example fix
# before vendor/bin/phpunit --generate-baseline=build/baseline.xml # build/ missing # after mkdir -p build vendor/bin/phpunit --generate-baseline=build/baseline.xml
Defensive patterns
Strategy: validation
Validate before calling
// Before --generate-baseline / Writer::write()
$dir = dirname($baselineFile);
if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new RuntimeException("Cannot create baseline directory {$dir}");
} Prevention
- Create output directories in CI before the step that writes baselines.
- Commit a .gitkeep in artifact directories so fresh clones have them.
- Validate target paths (no missing intermediate directories, no symlinked ghosts) in a preflight check.
When it happens
Trigger: vendor/bin/phpunit --generate-baseline=build/baseline.xml when build/ does not exist; a path through a missing intermediate directory; dirname resolving to an existing file; a symlink whose target does not exist so realpath() fails.
Common situations: Fresh clones without build artifacts; CI jobs assuming a directory created by an earlier step; refactoring output paths; typo in the target path.
Related errors
- File "%s" does not exist
- File "%s" does not have line %d
- Cannot read baseline %s, file does not exist
- Cannot read baseline %s: %s
- Cannot read baseline %s, version %d is not supported
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/91622f8b5d2c9e7a.
Report an issue: GitHub.