{"record":{"id":"0d6750fc4186a010","repo":"sebastianbergmann/phpunit","slug":"directory-s-does-not-exist-and-could-not-be-cre-0d6750","errorCode":null,"errorMessage":"Directory \"%s\" does not exist and could not be created","messagePattern":"Directory \"(.+?)\" does not exist and could not be created","errorType":"exception","errorClass":"PHPUnit\\Runner\\DirectoryDoesNotExistException","httpStatus":null,"severity":"error","filePath":"src/TextUI/Output/Printer/DefaultPrinter.php","lineNumber":100,"sourceCode":"\n            if (count($tmp) !== 2) {\n                throw new InvalidSocketException($out);\n            }\n\n            $stream = @fsockopen($tmp[0], (int) $tmp[1]);\n\n            if ($stream === false) {\n                throw new CannotOpenSocketException($tmp[0], (int) $tmp[1]);\n            }\n\n            $this->stream = $stream;\n            $this->isOpen = true;\n\n            return;\n        }\n\n        if (!$this->isPhpStream && !Filesystem::createDirectory(dirname($out))) {\n            throw new DirectoryDoesNotExistException(dirname($out));\n        }\n\n        $stream = fopen($out, 'wb');\n\n        assert($stream !== false);\n\n        $this->stream = $stream;\n        $this->isOpen = true;\n    }\n\n    public function print(string $buffer): void\n    {\n        assert($this->isOpen);\n\n        fwrite($this->stream, $buffer);\n    }\n\n    public function flush(): void","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/TextUI/Output/Printer/DefaultPrinter.php#L82-L118","documentation":"For regular (non-socket, non-php://) output targets, DefaultPrinter tries to create the parent directory of the output file via Filesystem::createDirectory(dirname($out)). If the directory does not exist and cannot be created, it throws DirectoryDoesNotExistException. This guards against silently losing output when fopen() would fail later.","triggerScenarios":"Constructing DefaultPrinter with a file target such as 'build/logs/results.txt' (or configuring report output paths) where the parent directory does not exist and mkdir() fails due to missing write permissions, a read-only filesystem, or open_basedir restrictions.","commonSituations":"CI images running as non-root trying to write under /var/www or other root-owned paths; read-only volume mounts in containers; output/cache paths that broke after the project was moved or the pipeline changed user.","solutions":["Pre-create the directory in the pipeline or bootstrap: `mkdir -p build/logs` before running PHPUnit","Grant write permission on the parent directory to the user running the tests (chown/chmod)","Point the output file into a writable location such as the workspace or a mounted volume","Use an absolute path you have verified is writable instead of a path inherited from a different working directory"],"exampleFix":"# before\n$ vendor/bin/phpunit --log-junit /var/www/app/build/results.xml\n# DirectoryDoesNotExistException: \"/var/www/app/build\" does not exist and could not be created\n\n# after\n$ mkdir -p /var/www/app/build && chmod u+w /var/www/app/build\n$ vendor/bin/phpunit --log-junit /var/www/app/build/results.xml","handlingStrategy":"validation","validationCode":"$target = 'build/logs/results.xml';\n$dir = dirname($target);\nif (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {\n    throw new RuntimeException(\"Cannot create output directory {$dir}\");\n}\nif (!is_writable($dir)) {\n    throw new RuntimeException(\"Output directory {$dir} is not writable\");\n}","typeGuard":null,"tryCatchPattern":"use PHPUnit\\TextUI\\Output\\Printer\\DirectoryDoesNotExistException;\n\ntry {\n    $printer = DefaultPrinter::from($target);\n} catch (DirectoryDoesNotExistException $e) {\n    // create the directory in a temporary location or fall back to stdout\n    $printer = DefaultPrinter::standardOutput();\n    error_log($e->getMessage());\n}","preventionTips":["Pre-create output directories in CI (`mkdir -p build/logs`) as an explicit pipeline step","Assert writability once in the bootstrap: is_writable(dirname($target)) for every configured report path","Keep all report paths inside the workspace/build directory rather than system paths like /var/www"],"tags":["phpunit","filesystem","permissions","output"],"backgroundTag":"directory-permission-denied","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}