sebastianbergmann/phpunit · error · PHPUnit\Util\PHP\PhpProcessException

Unable to write temporary file

Error message

Unable to write temporary file

What it means

JobRunner::run() executes a test in a separate PHP process (#[RunInSeparateProcess], process isolation). It first writes the generated job code to a temporary file using tempnam(sys_get_temp_dir(), 'phpunit_') plus file_put_contents(); if either step fails it throws PhpProcessException('Unable to write temporary file'). This is an environment failure in the temp directory, not a problem with your test code.

Source

Thrown at src/Util/PHP/JobRunner.php:102

        );

        EventFacade::emitter()->childProcessFinished($job->reason(), $result->stdout(), $result->stderr());
    }

    /**
     * @throws PhpProcessException
     */
    public function run(Job $job): Result
    {
        $temporaryFile = null;

        if ($job->hasInput()) {
            $temporaryFile = tempnam(sys_get_temp_dir(), 'phpunit_');

            if ($temporaryFile === false ||
                file_put_contents($temporaryFile, $job->code()) === false) {
                // @codeCoverageIgnoreStart
                throw new PhpProcessException(
                    'Unable to write temporary file',
                );
                // @codeCoverageIgnoreEnd
            }

            $job = new Job(
                $job->input(),
                $job->reason(),
                $job->phpSettings(),
                $job->environmentVariables(),
                $job->arguments(),
                null,
                $job->redirectErrors(),
                $job->requiresXdebug(),
            );
        }

        assert($temporaryFile !== '');

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Point TMPDIR at a writable directory before running PHPUnit: `TMPDIR=/workspace/tmp vendor/bin/phpunit`
  2. In containers, mount a writable tmpfs on /tmp (for example `--tmpfs /tmp:rw` in docker run)
  3. Free disk space or raise the quota if the volume is full
  4. If process isolation is not strictly required for that test, remove #[RunInSeparateProcess] / the isolation setting so no temp job file is needed

Example fix

# before
$ vendor/bin/phpunit --process-isolation
# PhpProcessException: Unable to write temporary file (read-only /tmp)

# after
$ mkdir -p /workspace/tmp && TMPDIR=/workspace/tmp vendor/bin/phpunit --process-isolation
Defensive patterns

Strategy: try-catch

Validate before calling

if (!is_writable(sys_get_temp_dir())) {
    throw new RuntimeException('Temp directory ' . sys_get_temp_dir() . ' is not writable; set TMPDIR');
}

Try / catch

use PHPUnit\Util\PHP\PhpProcessException;

try {
    $runner->run($job);
} catch (PhpProcessException $e) {
    if ($e->getMessage() === 'Unable to write temporary file') {
        // re-run with TMPDIR pointed at a writable dir, or skip process isolation
    }
}

Prevention

When it happens

Trigger: Running any test marked #[RunInSeparateProcess] (or with process isolation enabled globally) on a host where the temp directory is not writable: TMPDIR points somewhere unwritable, /tmp is a read-only filesystem, the disk is full, or open_basedir excludes the temp path.

Common situations: Hardened Docker images with a read-only root filesystem and no tmpfs on /tmp; CI runners with exhausted disk; misconfigured TMPDIR in systemd services or cron contexts; open_basedir shared-hosting style restrictions.

Related errors


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