{"record":{"id":"05c99e1175da964f","repo":"junit-team/junit5","slug":"error-redirecting-stderr-to-file-stderrpath","errorCode":null,"errorMessage":"Error redirecting stderr to file: ${stderrPath}","messagePattern":"Error redirecting stderr to file: (.+?)","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-platform-console/src/main/java/org/junit/platform/console/command/StandardStreamsHandler.java","lineNumber":69,"sourceCode":"\t\t\t\tthrow new JUnitException(\"Error redirecting stdout and stderr to file: \" + stdoutPath, ex);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (stdoutPath != null) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.stdout = new PrintStream(Files.newOutputStream(stdoutPath), true);\n\t\t\t\t}\n\t\t\t\tcatch (IOException ex) {\n\t\t\t\t\tthrow new JUnitException(\"Error redirecting stdout to file: \" + stdoutPath, ex);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stderrPath != null) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.stderr = new PrintStream(Files.newOutputStream(stderrPath), true);\n\t\t\t\t}\n\t\t\t\tcatch (IOException ex) {\n\t\t\t\t\tthrow new JUnitException(\"Error redirecting stderr to file: \" + stderrPath, ex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.stdout != null) {\n\t\t\tSystem.setOut(this.stdout);\n\t\t}\n\t\tif (this.stderr != null) {\n\t\t\tSystem.setErr(this.stderr);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void close() {\n\t\ttry {\n\t\t\tif (this.stdout != null) {\n\t\t\t\tthis.stdout.close();\n\t\t\t}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-console/src/main/java/org/junit/platform/console/command/StandardStreamsHandler.java#L51-L87","documentation":"StandardStreamsHandler.redirectStandardStreams() opens System.err's target file (Files.newOutputStream(stderrPath)) when --stderr is supplied with a path different from --stdout. An IOException during open is wrapped as a JUnitException. This is the stderr-only branch, symmetric to the stdout branch.","triggerScenarios":"Passing --stderr to a path that cannot be opened for writing while --stdout is null or different: missing parent dir, read-only location, path is a directory, or insufficient permissions.","commonSituations":"Separating test stdout from stderr but pointing stderr at an unwritable location; CI writing logs into a directory that another stage cleaned up; relative paths resolving against an unexpected working directory.","solutions":["Create and verify the parent directory is writable before launching.","Use an absolute file path (not a directory) with appropriate permissions.","If the redirect is optional, omit --stderr to write to the terminal."],"exampleFix":"# before\njava -jar junit-platform-console-standalone.jar execute --stderr /nonexistent/err.txt\n# after\nmkdir -p /tmp/out && java -jar junit-platform-console-standalone.jar execute --stderr /tmp/out/err.txt","handlingStrategy":"validation","validationCode":"// Before launching, verify the stderr target file is openable for writing.\nimport java.nio.file.*;\nPath err = Paths.get(stderrPath);\nif (Files.isDirectory(err)) throw new IllegalArgumentException(\"--stderr target is a directory: \" + err);\nPath parent = err.getParent();\nif (parent != null) Files.createDirectories(parent);\nif (!Files.isWritable(parent)) throw new IllegalArgumentException(\"--stderr parent not writable: \" + parent);\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pre-create the output directory before launching.","Use absolute paths for --stderr.","Verify the process user can write to the target directory."],"tags":["console-launcher","io","filesystem","stream-redirection"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}