junit-team/junit5 · error · JUnitException

Error redirecting stdout and stderr to file

Error message

Error redirecting stdout and stderr to file: ${stdoutPath}

What it means

StandardStreamsHandler.redirectStandardStreams() opens a single combined output stream for System.out and System.err when the same path is supplied for both (--stdout and --stderr point to one file). If Files.newOutputStream(path) throws IOException (e.g. permission denied, parent missing, path is a directory), a JUnitException wraps it.

Solutions

  1. Ensure the parent directory of the target file exists and is writable: create it and check permissions before running.
  2. Do not point --stdout/--stderr at a directory; supply a file path.
  3. If you do not need separate streams, this branch is fine — just fix the path; if you need them separate, use distinct paths (which then take the other branches).
  4. Use an absolute path to avoid ambiguity about the process working directory.

Example fix

# before
java -jar junit-platform-console-standalone.jar execute --stdout /no/such/dir/out.txt --stderr /no/such/dir/out.txt
# after
mkdir -p /tmp/out && java -jar junit-platform-console-standalone.jar execute --stdout /tmp/out/log.txt --stderr /tmp/out/log.txt
Defensive patterns

Strategy: validation

Validate before calling

// Before launching, ensure the shared stdout/stderr target file is writable.
import java.nio.file.*;
Path out = Paths.get(stdoutPath); // same path for --stdout and --stderr
if (Files.isDirectory(out)) throw new IllegalArgumentException("target is a directory: " + out);
Path parent = out.getParent();
if (parent != null) { Files.createDirectories(parent); }
if (Files.exists(parent) && !Files.isWritable(parent))
  throw new IllegalArgumentException("parent not writable: " + parent);

Prevention

When it happens

Trigger: Passing --stdout and --stderr to the same path where that file cannot be created/opened: a directory path, a read-only location, a missing parent directory, or a permissions issue.

Common situations: Redirecting console launcher output to a file path whose parent directory does not exist, is not writable, or is itself a directory; running in a sandboxed/CI environment with a restricted writable area.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/ceb043e7a8d3bcf0. Report an issue: GitHub.

Appendix: source

Thrown at junit-platform-console/src/main/java/org/junit/platform/console/command/StandardStreamsHandler.java:51

	 *
	 * <p>If the paths are the same, both streams are redirected to the same file.
	 *
	 * <p>The default charset is used for writing to the files.
	 *
	 * @param stdoutPath the file path for standard output, or {@code null} to
	 * indicate no redirection
	 * @param stderrPath the file path for standard error, or {@code null} to
	 * indicate no redirection
	 */
	public void redirectStandardStreams(@Nullable Path stdoutPath, @Nullable Path stderrPath) {
		if (isSameFile(stdoutPath, stderrPath)) {
			try {
				PrintStream commonStream = new PrintStream(Files.newOutputStream(stdoutPath), true);
				this.stdout = commonStream;
				this.stderr = commonStream;
			}
			catch (IOException ex) {
				throw new JUnitException("Error redirecting stdout and stderr to file: " + stdoutPath, ex);
			}
		}
		else {
			if (stdoutPath != null) {
				try {
					this.stdout = new PrintStream(Files.newOutputStream(stdoutPath), true);
				}
				catch (IOException ex) {
					throw new JUnitException("Error redirecting stdout to file: " + stdoutPath, ex);
				}
			}

			if (stderrPath != null) {
				try {
					this.stderr = new PrintStream(Files.newOutputStream(stderrPath), true);
				}
				catch (IOException ex) {
					throw new JUnitException("Error redirecting stderr to file: " + stderrPath, ex);

View on GitHub (pinned to f070c699a0)