karatelabs/karate · error · RuntimeException

image.write: needs (name|path, bytes)

Error message

image.write: needs (name|path, bytes)

What it means

The image.write verb writes image bytes either to a named baseline or to an explicit path and returns the absolute path written. It requires exactly (target, bytes); fewer than two arguments throws RuntimeException with this message.

Solutions

  1. Call with both args: karate.call('image.write', 'screenshot-home', screenshotBytes)
  2. Or with an explicit path: karate.call('image.write', '/abs/path/baseline.png', bytes)
  3. Verify the screenshot/byte variable is non-null before calling
  4. Remember karate.write cannot target absolute paths — use image.write for that

Example fix

// before
karate.call('image.write', 'screenshot-home'); // missing bytes
// after
def bytes = karate.scenario.embed(screenshot, 'image/png');
karate.call('image.write', 'screenshot-home', bytes);
Defensive patterns

Strategy: validation

Validate before calling

# karate
* if (!bytes) karate.abort('screenshot bytes missing before image.write')
* def path = karate.call('image.write', name, bytes)

Try / catch

try { return karate.call('image.write', target, bytes); } catch (Exception e) { if (('' + e).contains('needs (name|path, bytes)')) throw new IllegalStateException("image.write missing args: target=" + target + ", bytesNull=" + (bytes == null)); throw e; }

Prevention

When it happens

Trigger: karate.call('image.write') with only a name/path and no byte payload, or with no arguments at all — e.g. forgetting to pass the screenshot bytes, or the second argument being dropped in a dynamic call.

Common situations: Capturing a screenshot into a variable that is null/undefined so the call effectively has one argument; copy-pasting the resolve call shape (single arg) for write; building args programmatically and omitting the bytes entry.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at karate-image/src/main/java/io/karatelabs/ext/image/ImageApi.java:345

        String baselineLeaf = hasExt ? name : findBaselineLeaf(base);
        String baselineJoined = join(str(config.get("baselineDir")), baselineLeaf);

        Map<String, Object> out = new LinkedHashMap<>();
        out.put("baselinePath", absolute(baselineJoined));
        out.put("optionsPath", absolute(join(optionsDir(), base + ".json")));
        out.put("baselineExists", resourceExists(baselineJoined));
        return out;
    }

    /**
     * {@code image.write(name|path, bytes)} — write image bytes to the resolved baseline
     * (by name) or to an explicit path; returns the absolute path written. The recipe uses
     * this for auto-establish and programmatic rebase ({@code karate.write} can't target an
     * absolute path outside the report output dir).
     */
    private Object writeVerb(Object... args) {
        if (args.length < 2) {
            throw new RuntimeException("image.write: needs (name|path, bytes)");
        }
        String first = str(args[0]);
        String path = looksLikePath(first) ? first : str(resolve(first).get("baselinePath"));
        writeBytes(path, toBytes(args[1]));
        return absolute(path);
    }

    /** Existing {@code <baselineDir>/<base>.<ext>} for any known image ext, else default png. */
    private String findBaselineLeaf(String base) {
        String dir = str(config.get("baselineDir"));
        for (String ext : IMAGE_EXTS) {
            String leaf = base + "." + ext;
            Resource res = resolveResource(join(dir, leaf));
            if (res != null && res.exists()) {
                return leaf;
            }
        }
        return base + ".png";

View on GitHub (pinned to a22eb90246)