{"record":{"id":"9deec851fed38316","repo":"sebastianbergmann/phpunit","slug":"php-setting-s-contains-a-line-break-character","errorCode":null,"errorMessage":"PHP setting \"%s\" contains a line-break character, which is not permitted","messagePattern":"PHP setting \"(.+?)\" contains a line-break character, which is not permitted","errorType":"exception","errorClass":"PHPUnit\\Util\\PHP\\PhpProcessException","httpStatus":null,"severity":"error","filePath":"src/Util/PHP/JobRunner.php","lineNumber":410,"sourceCode":"     * Quoting is avoided for plain values so that boolean keywords such as\n     * `On` / `Off` keep their special INI semantics; wrapping them in quotes\n     * turns them into the literal strings `\"On\"` / `\"Off\"` and breaks\n     * settings like `output_buffering`.\n     *\n     * @throws PhpProcessException\n     */\n    private function processSettingValue(string $setting): string\n    {\n        $parts = explode('=', $setting, 2);\n\n        if (count($parts) !== 2) {\n            return $setting;\n        }\n\n        [$name, $value] = $parts;\n\n        if (str_contains($value, \"\\n\") || str_contains($value, \"\\r\")) {\n            throw new PhpProcessException(\n                sprintf(\n                    'PHP setting \"%s\" contains a line-break character, which is not permitted',\n                    $name,\n                ),\n            );\n        }\n\n        if (preg_match('/[;\"=${}|&~!\\[()^\\]]/', $value) !== 1) {\n            return $setting;\n        }\n\n        // Inside a double-quoted INI value, \\\\ collapses to \\ and \\\" to \",\n        // so both characters must be escaped to survive the round-trip\n        return $name . '=\"' . str_replace(['\\\\', '\"'], ['\\\\\\\\', '\\\\\"'], $value) . '\"';\n    }\n}\n","sourceCodeStart":392,"sourceCodeEnd":427,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Util/PHP/JobRunner.php#L392-L427","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make the ini value a single line in phpunit.xml — remove any literal line break inside the value attribute","Strip line breaks from dynamic values before they reach the configuration: `str_replace([\"\\r\", \"\\n\"], '', $value)`","Move multiline payloads (keys, certificates, scripts) out of ini settings and into a file or environment variable the test reads itself","Run the suite once with process isolation after config changes to catch this before CI does"],"exampleFix":"<!-- before -->\n<php>\n  <ini name=\"error_reporting\" value=\"E_ALL\n&amp; ~E_DEPRECATED\"/>\n</php>\n\n<!-- after -->\n<php>\n  <ini name=\"error_reporting\" value=\"E_ALL &amp; ~E_DEPRECATED\"/>\n</php>","handlingStrategy":"validation","validationCode":"$value = (string) $iniValue;\nif (str_contains($value, \"\\n\") || str_contains($value, \"\\r\")) {\n    throw new InvalidArgumentException('PHP ini values must be single-line: ' . $name);\n}","typeGuard":null,"tryCatchPattern":"use PHPUnit\\Util\\PHP\\PhpProcessException;\n\ntry {\n    // start process-isolated run with configured settings\n} catch (PhpProcessException $e) {\n    if (str_contains($e->getMessage(), 'line-break character')) {\n        // fix the offending <ini> value in phpunit.xml, then re-run\n    }\n}","preventionTips":["Lint phpunit.xml for multiline attribute values before enabling process isolation","Trim environment-derived values: trim($value, \" \\r\\n\") before injecting them into config","Store multiline payloads (keys, certs) in files referenced by path, not in ini values","Run one process-isolated smoke test locally after changing <php> settings"],"tags":["phpunit","process-isolation","ini-settings","config-validation"],"backgroundTag":"config-value-validation","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}