{"id":"11f3c5649b99f535","repo":"junit-team/junit5","slug":"failed-to-write-report","errorCode":null,"errorMessage":"Failed to write report","messagePattern":"Failed to write report","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"documentation/src/tools/java/org/junit/api/tools/ApiReportGenerator.java","lineNumber":79,"sourceCode":"\t\t\tvar apiReport = generateReport(scanResult);\n\n\t\t\t// ApiReportWriter reportWriter = new MarkdownApiReportWriter(apiReport);\n\t\t\tApiReportWriter reportWriter = new AsciidocApiReportWriter(apiReport);\n\t\t\t// ApiReportWriter reportWriter = new HtmlApiReportWriter(apiReport);\n\n\t\t\t// reportWriter.printReportHeader(new PrintWriter(System.out, true));\n\n\t\t\t// Print report for all Usage enum constants\n\t\t\t// reportWriter.printDeclarationInfo(new PrintWriter(System.out, true), EnumSet.allOf(Status.class));\n\n\t\t\t// Print report only for specific Status constants, defaults to only EXPERIMENTAL\n\t\t\tparseArgs(args).forEach((status, opener) -> {\n\t\t\t\ttry (var stream = opener.openStream()) {\n\t\t\t\t\tvar writer = new PrintWriter(stream == null ? System.out : stream, true, UTF_8);\n\t\t\t\t\treportWriter.printDeclarationInfo(writer, EnumSet.of(status));\n\t\t\t\t}\n\t\t\t\tcatch (IOException e) {\n\t\t\t\t\tthrow new UncheckedIOException(\"Failed to write report\", e);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t// -------------------------------------------------------------------------\n\n\tprivate static Map<Status, StreamOpener> parseArgs(String[] args) {\n\t\tMap<Status, StreamOpener> outputByStatus = new EnumMap<>(Status.class);\n\t\tif (args.length == 0) {\n\t\t\toutputByStatus.put(Status.EXPERIMENTAL, () -> null);\n\t\t}\n\t\telse {\n\t\t\tArrays.stream(args) //\n\t\t\t\t\t.map(arg -> arg.split(\"=\", 2)) //\n\t\t\t\t\t.forEach(parts -> outputByStatus.put(//\n\t\t\t\t\t\tStatus.valueOf(parts[0]), //\n\t\t\t\t\t\t() -> parts.length < 2 //","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/documentation/src/tools/java/org/junit/api/tools/ApiReportGenerator.java#L61-L97","documentation":"Thrown as an UncheckedIOException by the ApiReportGenerator documentation build tool when writing the generated API report to an output stream fails with an IOException. This tool is an internal documentation generator (invoked via main()) that scans the org.junit packages with ClassGraph and writes Asciidoc/Markdown reports. It is not part of the runtime JUnit Jupiter API surface used by test authors.","triggerScenarios":"Running ApiReportGenerator with a STATUS=path argument where the path is unwritable, the parent directory does not exist, the disk is full, or the stream is closed mid-write. Also triggered if System.out itself is in a bad state (e.g., closed by a prior redirect).","commonSituations":"Documentation builds where the output directory was not created first, CI runners with read-only workspaces, permission denied on the target path, or a typo in the STATUS=outfile argument.","solutions":["Ensure the parent directory of the output file exists and is writable: mkdir -p $(dirname <outfile>) before running the generator.","Check available disk space and write permissions on the target path.","If the path argument is omitted (parseArgs returns a null opener → writes to System.out), verify stdout is not closed/redirected to an invalid target.","Re-run with no argument (writes to stdout) to isolate whether the failure is path-specific."],"exampleFix":"// before\njava ApiReportGenerator EXPERIMENTAL=/nonexistent/dir/report.adoc\n\n// after\nmkdir -p /tmp/reports && java ApiReportGenerator EXPERIMENTAL=/tmp/reports/report.adoc","handlingStrategy":"try-catch","validationCode":"Path out = Path.of(args[1]);\nPath parent = out.getParent();\nif (parent != null && !Files.isDirectory(parent)) {\n    Files.createDirectories(parent);\n}\nif (!Files.isWritable(parent == null ? Path.of(\".\") : parent)) {\n    throw new IllegalStateException(\"output dir not writable: \" + parent);\n}","typeGuard":null,"tryCatchPattern":"try {\n    apiReportGenerator.run(status, outputPath);\n} catch (UncheckedIOException e) {\n    throw new BuildException(\"Cannot write API report to \" + outputPath + \": \" + e.getCause().getMessage(), e);\n}","preventionTips":["Run ApiReportGenerator from the repo root with output paths under a known-writable build directory (e.g. build/docs/api).","Create output parent directories in the build script before invoking the generator.","Treat this tool as build infrastructure, not runtime test code."],"tags":["io","documentation-tool","filesystem","build"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}