{"record":{"id":"7ce3c63629421fda","repo":"karatelabs/karate","slug":"failed-to-create-junit-xml-output-directory","errorCode":null,"errorMessage":"Failed to create JUnit XML output directory: {}","messagePattern":"Failed to create JUnit XML output directory: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/output/JunitXmlReportListener.java","lineNumber":71,"sourceCode":"\n    /**\n     * Create a new JUnit XML report listener.\n     *\n     * @param outputDir the base output directory (subfolder will be created)\n     */\n    public JunitXmlReportListener(Path outputDir) {\n        this.outputDir = outputDir.resolve(SUBFOLDER);\n    }\n\n    @Override\n    public void onSuiteStart(Suite suite) {\n        // Create output directory eagerly\n        try {\n            if (!Files.exists(outputDir)) {\n                Files.createDirectories(outputDir);\n            }\n        } catch (Exception e) {\n            logger.warn(\"Failed to create JUnit XML output directory: {}\", e.getMessage());\n        }\n    }\n\n    @Override\n    public void onFeatureEnd(FeatureResult result) {\n        // Sort scenarios for deterministic ordering\n        result.sortScenarioResults();\n\n        // Serialize AND write here, on the feature's own thread. The write used to be handed\n        // to a single-thread executor with an unbounded queue; measured over a many-feature\n        // suite that thread was idle — its share of the work was a few percent of wall-clock —\n        // so the queue could only ever grow, never help. Writing inline also means a feature\n        // cannot complete until its report is on disk, which bounds what is held in memory.\n        try {\n            JunitXmlWriter.writeSerialized(JunitXmlWriter.fileNameFor(result),\n                    JunitXmlWriter.serializeFeature(result), outputDir);\n        } catch (Exception e) {\n            logger.warn(\"Failed to write JUnit XML for {}: {}\", result.getDisplayName(), e.getMessage());","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/output/JunitXmlReportListener.java#L53-L89","documentation":"JunitXmlReportListener.onSuiteStart() eagerly creates the JUnit XML output directory so later per-feature writes succeed. If directory creation fails, the listener warns and continues; subsequent per-feature XML writes may then also fail.","triggerScenarios":"Files.createDirectories(outputDir) throwing at suite start — parent path does not exist and cannot be created, permission denied, or the path exists as a regular file.","commonSituations":"Misconfigured outputDir (typo, points to a file); running CI as a user without write permission on the target volume; network/overlay mounts unavailable at suite start.","solutions":["Fix the outputDir configuration so it points to a writable, non-existent-or-directory path","Pre-create the parent directories manually or fix permissions (chown/chmod) for the process user","Check the path is not occupied by a regular file","Verify the volume (e.g. CI workspace mount) is mounted and writable before the suite runs"],"exampleFix":"// before\nkarate.outputDir=target/surefire-reports/karate (parent missing, read-only CI)\n// after: ensure parent exists and is writable\nmkdir -p target/surefire-reports && chmod u+w target/surefire-reports","handlingStrategy":"validation","validationCode":"Path dir = Paths.get(karateOutputDir);\nif (Files.exists(dir) && !Files.isDirectory(dir))\n    throw new IllegalStateException(\"outputDir is a file: \" + dir);\nFiles.createDirectories(dir); // fail fast before suite start","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate karate.outputDir in CI setup before launching tests","Ensure the CI user owns or can write the target directory","Watch for output paths accidentally pointing at regular files"],"tags":["junit-xml","filesystem","directory-creation","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}