karatelabs/karate · error · RuntimeException
image.write: failed to write
Error message
image.write: failed to write '{p}': {message} What it means
writeBytes writes image bytes to the target path, creating parent directories as needed. Any failure in directory creation or file writing (permissions, missing filesystem, IO error) is wrapped in a RuntimeException identifying the path and underlying message.
Solutions
- Read the wrapped cause and path in the message; check whether the target directory exists and is writable
- Fix permissions on the report output directory (chmod/chown or fix the mount as read-write)
- Free disk space or raise the quota if the cause is no-space
- If overriding the path explicitly, pass a valid absolute path in a writable location
Example fix
// before
chmod 444 target/reports
karate.call('image.write', 'shot', bytes); // fails
// after
chmod 755 target/reports
karate.call('image.write', 'shot', bytes); Defensive patterns
Strategy: try-catch
Validate before calling
# karate
* def outDir = karate.properties['karate.outputDir']
* if (!karate.os.path(outDir)) karate.call('mkoutputdir', outDir) // ensure writable dir exists Try / catch
try { return karate.call('image.write', name, bytes); } catch (Exception e) { if (('' + e).startsWith('image.write: failed to write')) { karate.warn('write failed: ' + e.message); return null; } throw e; } Prevention
- Ensure the report output directory exists and is writable before the suite starts
- Check disk space/quota in CI before long image suites
- Avoid read-only mounts for the workspace
- Use simple absolute paths without illegal characters
When it happens
Trigger: Calling image.write (directly or via writeVerb) where the resolved target path's parent cannot be created or the file cannot be written — e.g. read-only report output dir, no space left on device, invalid path characters, or target inside a file (not directory).
Common situations: CI containers with a read-only workspace; report output dir deleted/replaced by a symlink mid-run; writing to /reports on a volume mounted read-only; disk quota exceeded on long suites; path containing illegal characters on Windows.
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 read bytes from
- image.diff: need a name or a baseline (and a latest)
- image.resolve: 'name' is required
- image.write: needs (name|path, bytes)
- image: failed to read options
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/a0232b6c6b35f521.
Report an issue: GitHub.
Appendix: source
Thrown at karate-image/src/main/java/io/karatelabs/ext/image/ImageApi.java:469
private boolean resourceExists(String p) {
Resource r = resolveResource(p);
return r != null && r.exists();
}
private void writeBytes(String p, byte[] bytes) {
try {
Resource r = resolveResource(p);
java.nio.file.Path target = r != null ? r.getPath() : null;
if (target == null) {
target = new java.io.File(p).toPath();
}
java.nio.file.Path parent = target.getParent();
if (parent != null) {
java.nio.file.Files.createDirectories(parent);
}
java.nio.file.Files.write(target, bytes);
} catch (Exception e) {
throw new RuntimeException("image.write: failed to write '" + p + "': " + e.getMessage(), e);
}
}
// ---- arg parsing + small helpers ----
private static Map<String, Object> parseArgs(Object... args) {
Map<String, Object> out = new LinkedHashMap<>();
if (args.length == 1 && args[0] instanceof Map<?, ?> map) {
map.forEach((k, v) -> out.put(String.valueOf(k), v));
return out;
}
if (args.length > 0) {
// a bare-name String → resolved baseline + <name> options; a path-looking String
// (this:/classpath:/file:/contains a slash) → explicit baseline; bytes → baseline
Object first = args[0];
if (first instanceof String s && !looksLikePath(s)) {
out.put("name", s);
} else {View on GitHub (pinned to a22eb90246)