karatelabs/karate · error · RuntimeException

embed() needs at least one argument: data

Error message

embed() needs at least one argument: data

What it means

karate.embed() attaches content (bytes, a file path, or URL data) to the current step's report, and requires at least the data argument. Karate throws this when embed is called with zero arguments, as there is nothing to embed.

Solutions

  1. Pass the content as the first argument: karate.embed(bytes) or karate.embed({parts: [...], ...}) for multipart embeds.
  2. For file/report attachments, embed a byte array (e.g. from karate.readBytes or an HTTP response) or a map with parts entries.
  3. Verify the variable holding the content is assigned before calling embed.

Example fix

// before
karate.embed();

// after
var bytes = karate.readBytes('classpath:screenshot.png');
karate.embed(bytes, 'image/png');
Defensive patterns

Strategy: validation

Validate before calling

if (data == null) { throw new Error('embed content required'); } karate.embed(data, mime);

Type guard

function isEmbeddable(x) { return x instanceof Array || x instanceof Uint8Array || typeof x === 'string' || (x != null && typeof x === 'object'); }

Try / catch

try { karate.embed(bytes); } catch (e) { if (String(e.message).includes('needs at least one argument')) { karate.log('nothing to embed'); } throw e; }

Prevention

When it happens

Trigger: `karate.embed()` called with no arguments from JS; an undefined variable passed where arity is checked before unwrapping.

Common situations: Building report attachments dynamically where the byte array failed to materialize; copying embed examples without arguments; calling embed conditionally when the variable wasn't set.

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/01dfba6967b8e195. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJsBase.java:503

    }

    /**
     * Embed content in the report. Two forms:
     * <ul>
     *   <li><b>Single-part (legacy):</b> {@code embed(data, mime?, name?)} — auto-detects MIME
     *       when omitted.</li>
     *   <li><b>Multi-part (object):</b> {@code embed({ name, parts:[{role, mime?, data|path|url}], meta })}
     *       — for rich embeds (e.g. image-comparison). Dispatched when the first arg is a Map
     *       carrying a {@code parts} list. Each part: {@code role} is required;
     *       {@code data} (bytes / Uint8Array) or {@code path} (a resource string core reads to
     *       bytes) or {@code url} (a report-relative asset the caller wrote); {@code mime} is
     *       auto-detected from the bytes when omitted.</li>
     * </ul>
     */
    JavaInvokable embed() {
        return args -> {
            if (args.length < 1) {
                throw new RuntimeException("embed() needs at least one argument: data");
            }
            Object first = unwrapJs(args[0]);
            if (first instanceof Map<?, ?> map && map.get("parts") instanceof List) {
                LogContext.get().embed(toMultiPartEmbed(map));
                return null;
            }
            // single-part (legacy)
            String mimeType = args.length > 1 && args[1] != null
                    ? args[1].toString() : KarateJsUtils.detectMimeType(first);
            String name = args.length > 2 ? args[2].toString() : null;
            byte[] data = KarateJsUtils.convertToBytes(first);
            LogContext.get().embed(data, mimeType, name);
            return null;
        };
    }

    private StepResult.Embed toMultiPartEmbed(Map<?, ?> map) {
        String name = map.get("name") != null ? map.get("name").toString() : null;

View on GitHub (pinned to a22eb90246)