{"record":{"id":"0d14af7e6a48bcc1","repo":"karatelabs/karate","slug":"failed-to-write-feature-html-for","errorCode":null,"errorMessage":"Failed to write feature HTML for {}: {}","messagePattern":"Failed to write feature HTML for (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/output/HtmlReportListener.java","lineNumber":135,"sourceCode":"        //\n        // Rendering used to be handed to a single-thread executor with an unbounded queue, on\n        // the reasoning that templating and IO should stay off the hot path. Measured, the\n        // opposite was true: rendering a feature page cost ~3x the suite's entire wall-clock\n        // when summed over all features, so that one thread could never keep up and its queue\n        // grew for the whole run — holding a complete page model per queued feature. Peak heap\n        // then tracked the number of features, not the number in flight. It was the single\n        // largest memory consumer with reports on, and it was noisy run-to-run because what\n        // was really being measured was a race between producer and writer.\n        //\n        // Inline, the cost is shared across every feature thread instead of serialized onto\n        // one, and a feature cannot complete until its page is on disk — so the page model is\n        // live for one feature per thread rather than for the whole suite.\n        try {\n            ensureResourcesCopied();\n            HtmlReportWriter.renderFeatureHtml(\n                    HtmlReportWriter.prepareFeatureData(result, outputDir), outputDir, reportAssets);\n        } catch (Exception e) {\n            logger.warn(\"Failed to write feature HTML for {}: {}\", result.getDisplayName(), e.getMessage());\n        }\n    }\n\n    /**\n     * A feature's result reduced to what the suite-end pages read.\n     *\n     * <p>Retaining {@code result.toJson()} whole is what made report generation the largest\n     * memory consumer in a long run: the map holds every step, its log text, its embeds and\n     * the full result tree of every {@code karate.call()} it made, and it stays reachable\n     * until the last feature finishes. Memory then scales with the size of the whole suite.\n     * Measured on a 60-calls-per-scenario shape, retention was roughly 1.5 MB per scenario\n     * with reports on against 0.43 MB with them off — reporting cost more than execution.\n     *\n     * <p>Neither consumer needs any of that. {@code buildFeatureSummaryList} and\n     * {@code buildTimelineData} read only feature-level identity and status plus a handful\n     * of per-scenario fields; {@code stepResults} is never touched at suite end. The\n     * per-feature HTML — the one thing that does need step detail — is written eagerly in\n     * {@link #onFeatureEnd} from the {@link FeatureResult} itself, before this reduction.","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/output/HtmlReportListener.java#L117-L153","documentation":"WARN log from HtmlReportListener.onFeatureEnd when rendering/copying the per-feature HTML report page throws. The feature's execution results are unaffected — only the per-feature HTML page for that feature fails to be written; the exception message is logged and swallowed.","triggerScenarios":"Exception in ensureResourcesCopied(), HtmlReportWriter.prepareFeatureData(), or renderFeatureHtml() — typically an I/O failure writing into the report output directory, or resource-copy failure (classpath assets unavailable, read-only output dir).","commonSituations":"Report output directory deleted or made read-only mid-run (e.g. CI cleaner); disk full during long suites; antivirus locking files on Windows; template resource missing from the classpath after packaging changes.","solutions":["Inspect the logged exception message to find the failing write and its path.","Ensure the report output directory remains writable for the whole suite run.","Verify disk space and that nothing (CI cleaner, antivirus) touches the output dir during the run.","Confirm karate-core's report resources are intact in the jar/classpath (rebuild if corrupted)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// the listener already catches and logs; treat the log line as a report-completeness signal\nif (logContains(\"Failed to write feature HTML\")) {\n    verify(reportDir).resolve(expectedFeatureHtml).exists(); // re-generate if missing\n}","preventionTips":["Keep the report output directory writable for the entire suite duration.","Exclude the report dir from CI cleaners and antivirus scans during the run.","Monitor disk space on long suites."],"tags":["html-report","filesystem","report-writer"],"backgroundTag":"file-write-failed","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"}