karatelabs/karate · warning

Failed to create report directories

Error message

Failed to create report directories: {}

What it means

WARN log from HtmlReportListener.onSuiteStart when the eager Files.createDirectories calls for the report output folder (subfolder and 'res') fail. The listener continues, and directory creation is likely retried later by the report writer, but early report files may be missing if the underlying cause (permissions, bad path) persists.

Solutions

  1. Fix the configured report output directory to a writable, non-existent-as-file location.
  2. Check parent-directory permissions (`ls -ld <parent>`) and disk space.
  3. In containers/CI, mount or create a writable output volume.
  4. Verify no file exists at the same path where the directory must be created.

Example fix

// before: unwritable path in runner
HtmlReport.handleResult("target/surefire-reports"); // if target/ is read-only
// after
HtmlReport.handleResult(System.getProperty("java.io.tmpdir") + "/karate-report");
Defensive patterns

Strategy: validation

Validate before calling

Path out = Path.of(reportDir);
if (out.toFile().exists() && !out.toFile().isDirectory()) throw new IllegalStateException("report path is a file: " + out);
if (!Files.isWritable(out.getParent() != null ? out.getParent() : out)) throw new IllegalStateException("report dir not writable: " + out);

Prevention

When it happens

Trigger: Suite start with an outputDir that cannot be created: parent directory missing and uncreatable, no write permission on the parent, outputDir points to an existing regular file, or a read-only filesystem/volume.

Common situations: Read-only CI workspace or container filesystem; report path pointing into a nonexistent protected location; outputDir colliding with an existing file; Windows path with invalid characters; disk full.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/187b2946d5faae50. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/output/HtmlReportListener.java:102

    }

    @Override
    public void onSuiteStart(Suite suite) {
        suiteStartTime = System.currentTimeMillis();
        threadCount = suite.threadCount;
        reportAssets = suite.getReportAssets();
        this.suite = suite;

        // Embed file names use a 001_, 002_, ... sequence; reset per suite so
        // numbers don't bleed across runs in the same JVM (e.g. test suites).
        HtmlReportWriter.resetEmbedCounter();

        // Create directories eagerly
        try {
            Files.createDirectories(outputDir.resolve(SUBFOLDER));
            Files.createDirectories(outputDir.resolve("res"));
        } catch (Exception e) {
            logger.warn("Failed to create report directories: {}", e.getMessage());
        }
    }

    @Override
    public void onFeatureEnd(FeatureResult result) {
        // Sort scenarios for deterministic ordering in reports
        result.sortScenarioResults();

        // Collect feature data using toJson() format, reduced to what the suite-end pages
        // actually read. The per-feature HTML below is written from the FeatureResult
        // itself, so nothing here needs the step detail.
        featureMaps.add(summaryJson(result));

        // Extract the page model and render it, both here, on the feature's own thread.
        //
        // Rendering used to be handed to a single-thread executor with an unbounded queue, on
        // the reasoning that templating and IO should stay off the hot path. Measured, the
        // opposite was true: rendering a feature page cost ~3x the suite's entire wall-clock

View on GitHub (pinned to a22eb90246)