karatelabs/karate · warning
Failed to close JSONL event stream
Error message
Failed to close JSONL event stream: {} What it means
At the end of Suite.run(), the JSONL event writer is removed from the listener list and closed. If closing the underlying stream throws (IO error flushing final bytes, stream already closed by something else), the warning is logged and shutdown continues — the suite result is unaffected, but the JSONL file may be truncated.
Solutions
- Verify the JSONL file is complete/parseable; if truncated, re-run with more disk headroom
- Ensure only one Suite owns the output directory and its event writer
- Check for disk-full or quota errors on the output volume around test end time
- If only the warning appears and results are correct, it is safe to ignore the truncated event stream
Example fix
// before: two suites writing the same dir in one JVM Suite a = new Suite(opts with outputDir "target/karate"); Suite b = new Suite(opts with outputDir "target/karate"); // after: distinct output dirs per suite Suite a = new Suite(opts with outputDir "target/karate-a"); Suite b = new Suite(opts with outputDir "target/karate-b");
Defensive patterns
Strategy: try-catch
Validate before calling
// after the run, verify the JSONL file ends with a complete line
java.nio.file.Path f = java.nio.file.Path.of(outputDir, "karate-events.jsonl");
String tail = java.nio.file.Files.readString(f).stripTrailing();
if (!tail.endsWith("}")) throw new IllegalStateException("JSONL stream truncated (close failed?)"); Try / catch
try {
suite.run();
} finally {
// Suite already warns on close failure; validate the artifact
if (!isCompleteJsonl(outputDir)) logger.warn("JSONL event file incomplete — treat as best-effort");
} Prevention
- Give each Suite its own output directory so writers never share file handles
- Ensure enough disk space for the full event log (large runs write a lot)
- Avoid unmounting/tearing down CI workspace volumes before the JVM exits
- Treat JSONL as best-effort telemetry; never depend on it for pass/fail assertions
When it happens
Trigger: Suite.run() teardown where jsonlWriter.close() throws: disk became full while flushing the final buffer, underlying file handle already closed, filesystem error on the output volume, or an OS-level IO failure.
Common situations: CI agents unmounting volumes mid-teardown; two Suite instances sharing an output dir so one closes the file first; disk-quota exhaustion during a large run.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to initialize JSONL event stream
- Failed to read bytes from
- ext ' ': resource vanished after validation
- ext ' ': failed reading
- Failed to create session directory: " + directory
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/960dcc710b408679.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/Suite.java:603
// Fire SUITE_EXIT event
fireEvent(SuiteRunEvent.exit(this, result));
} finally {
if (result.getEndTime() == 0) {
result.setEndTime(System.currentTimeMillis());
}
// Shutdown driver provider if one exists
if (driverProvider != null) {
driverProvider.shutdown();
}
// Close JSONL event writer
if (jsonlWriter != null) {
try {
removeJsonlListener(jsonlWriter);
jsonlWriter.close();
} catch (Exception e) {
logger.warn("Failed to close JSONL event stream: {}", e.getMessage());
}
}
// Ext onShutdown — best-effort; exceptions are logged + dropped per K43.
if (bootBinding != null) {
for (Ext ext : bootBinding.getExts()) {
try {
ext.onShutdown();
} catch (Exception e) {
logger.warn("ext onShutdown failed ({}): {}",
ext.getClass().getName(), e.getMessage());
}
removeJsonlListener(ext);
}
}
// Notify listeners
for (ResultListener listener : resultListeners) {View on GitHub (pinned to a22eb90246)