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

PHP setting "%s" contains a line-break character, which is n

Error message

PHP setting "%s" contains a line-break character, which is not permitted

What it means

For process isolation, JobRunner converts configured PHP settings into `-d name=value` command-line arguments for the child process. processSettingValue() rejects any value containing \n or \r with PhpProcessException, because a line break would corrupt or inject into the child's command line. This is a data-validation error in the configured settings, triggered whenever a separate-process test runs with such a setting.

Source

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

     * Quoting is avoided for plain values so that boolean keywords such as
     * `On` / `Off` keep their special INI semantics; wrapping them in quotes
     * turns them into the literal strings `"On"` / `"Off"` and breaks
     * settings like `output_buffering`.
     *
     * @throws PhpProcessException
     */
    private function processSettingValue(string $setting): string
    {
        $parts = explode('=', $setting, 2);

        if (count($parts) !== 2) {
            return $setting;
        }

        [$name, $value] = $parts;

        if (str_contains($value, "\n") || str_contains($value, "\r")) {
            throw new PhpProcessException(
                sprintf(
                    'PHP setting "%s" contains a line-break character, which is not permitted',
                    $name,
                ),
            );
        }

        if (preg_match('/[;"=${}|&~!\[()^\]]/', $value) !== 1) {
            return $setting;
        }

        // Inside a double-quoted INI value, \\ collapses to \ and \" to ",
        // so both characters must be escaped to survive the round-trip
        return $name . '="' . str_replace(['\\', '"'], ['\\\\', '\\"'], $value) . '"';
    }
}

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Make the ini value a single line in phpunit.xml — remove any literal line break inside the value attribute
  2. Strip line breaks from dynamic values before they reach the configuration: `str_replace(["\r", "\n"], '', $value)`
  3. Move multiline payloads (keys, certificates, scripts) out of ini settings and into a file or environment variable the test reads itself
  4. Run the suite once with process isolation after config changes to catch this before CI does

Example fix

<!-- before -->
<php>
  <ini name="error_reporting" value="E_ALL
&amp; ~E_DEPRECATED"/>
</php>

<!-- after -->
<php>
  <ini name="error_reporting" value="E_ALL &amp; ~E_DEPRECATED"/>
</php>
Defensive patterns

Strategy: validation

Validate before calling

$value = (string) $iniValue;
if (str_contains($value, "\n") || str_contains($value, "\r")) {
    throw new InvalidArgumentException('PHP ini values must be single-line: ' . $name);
}

Try / catch

use PHPUnit\Util\PHP\PhpProcessException;

try {
    // start process-isolated run with configured settings
} catch (PhpProcessException $e) {
    if (str_contains($e->getMessage(), 'line-break character')) {
        // fix the offending <ini> value in phpunit.xml, then re-run
    }
}

Prevention

When it happens

Trigger: Running a test with #[RunInSeparateProcess] (or global process isolation) while phpunit.xml contains a `<php><ini name="..." value="..."/></php>` setting whose value spans multiple lines, or the value is injected from an environment variable that carries a trailing newline.

Common situations: Copy-pasted multiline ini values into phpunit.xml; values sourced from .env files or CI secret variables that include a newline (common with base64-decoded secrets); values assembled with heredocs in bootstrap code.

Related errors


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