junit-team/junit5 · error · UncheckedIOException
Failed to copy files to the output directory
Error message
Failed to copy files to the output directory
What it means
Thrown as UncheckedIOException inside TestReporter.publishDirectory(Path) when copying a file from the source directory tree to the report output directory fails with an IOException (Files.copy or Files.createDirectories inside the Files.walk loop). It wraps the underlying I/O error so the test fails loudly rather than silently producing a partial directory.
Source
Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/TestReporter.java:160
@API(status = MAINTAINED, since = "5.13.3")
default void publishDirectory(Path directory) {
Preconditions.notNull(directory, "directory must not be null");
Preconditions.condition(Files.exists(directory), () -> "directory must exist: " + directory);
Preconditions.condition(Files.isDirectory(directory), () -> "path must represent a directory: " + directory);
publishDirectory(directory.getFileName().toString(), path -> {
try (Stream<Path> stream = Files.walk(directory)) {
stream.forEach(source -> {
Path destination = path.resolve(directory.relativize(source));
try {
if (Files.isDirectory(source)) {
Files.createDirectories(destination);
}
else {
Files.copy(source, destination, REPLACE_EXISTING);
}
}
catch (IOException e) {
throw new UncheckedIOException("Failed to copy files to the output directory", e);
}
});
}
});
}
/**
* Publish a file with the supplied name and media type written by the supplied
* action and attach it to the current test or container.
*
* <p>The {@link Path} passed to the supplied action will be relative to the
* report output directory, but it is up to the action to write the file.
*
* @param name the name of the file to be published; never {@code null} or
* blank and must not contain any path separators
* @param mediaType the media type of the file; never {@code null}; use
* {@link org.junit.jupiter.api.extension.MediaType#APPLICATION_OCTET_STREAM}
* if unknownView on GitHub (pinned to 956246301e)
Solutions
- Verify the report output directory is writable and has enough free space before publishing.
- Ensure the source directory is stable (no concurrent mutation) during publishDirectory.
- Use unique directory/file names per test (e.g., prefixed with the test display name) to avoid parallel write collisions.
- If the wrapped IOException is transient (e.g., short disk hiccup), re-run the test on a healthy worker.
Example fix
// before
testReporter.publishDirectory(Path.of("build/output")); // fails if build/output not writable
// after — preflight the source and ensure the output root is writable
Path src = Path.of("build/output");
if (!Files.isReadable(src) || !Files.isDirectory(src)) {
throw new IllegalStateException("source dir missing: " + src);
}
testReporter.publishDirectory(src); Defensive patterns
Strategy: try-catch
Validate before calling
Path src = /* directory to publish */;
if (!Files.isDirectory(src) || !Files.isReadable(src)) {
throw new IllegalStateException("source directory not readable: " + src);
}
// best-effort stability check: snapshot the entry list
long count;
try (var s = Files.walk(src)) { count = s.count(); }
// ensure report output root is writable by publishing a tiny probe first if unsure Try / catch
try {
testReporter.publishDirectory(src);
} catch (java.io.UncheckedIOException e) {
// log and fall back to publishing individual files, or mark the test as incomplete
System.err.println("publishDirectory failed: " + e.getCause());
throw e;
} Prevention
- Ensure the report output directory is writable before publishing (set junit.platform.output.* / launcher config correctly).
- Do not mutate the source directory while publishDirectory is running.
- Use unique filenames per test to avoid parallel write races.
When it happens
Trigger: Calling testReporter.publishDirectory(dirPath) where dirPath is readable but the report output directory is not writable, a source file is deleted/made unreadable during the walk, the output filesystem is full, or a destination path cannot be created (e.g., a name collision with an existing file where a directory is expected).
Common situations: Tests that publish generated artifacts (screenshots, coverage dumps, HTML reports) to a report dir; CI sandboxes where the output root is read-only or ephemeral; parallel tests racing on the same output filename.
Related errors
- Failed to create default temp directory
- Failed to write report
- Failed to publish path
- Failed to create output directory
- temp directory must be a directory
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/1dfee3b1eef67c37.json.
Report an issue: GitHub.