karatelabs/karate · error · RuntimeException

embed(): part ' ' needs 'data', 'path', or 'url

Error message

embed(): part '{role}' needs 'data', 'path', or 'url'

What it means

A multipart embed part must provide content via one of 'data' (bytes/string), 'path' (file path), or 'url'. Karate throws this naming the part's role when none of these keys are present, since there is no content to attach to the report.

Solutions

  1. Add one of data, path, or url to every part: {role: 'image', path: 'shot.png'}, {role: 'log', data: text}, or {role: 'remote', url: 'https://...'}.
  2. Check for misspelled keys (bytes/file/source are not recognized).
  3. If the content is unavailable, either drop the part or embed a placeholder so the parts array stays valid.

Example fix

// before
karate.embed({ parts: [{ role: 'log', mime: 'text/plain' }] });

// after
karate.embed({ parts: [{ role: 'log', mime: 'text/plain', data: 'step log text' }] });
Defensive patterns

Strategy: validation

Validate before calling

if (parts.some(function(p){ return p.data == null && p.path == null && p.url == null; })) { throw new Error('part needs data, path, or url'); }

Type guard

function hasContent(p) { return p != null && (p.data != null || p.path != null || p.url != null); }

Try / catch

try { karate.embed({ parts: parts }); } catch (e) { if (String(e.message).includes("needs 'data', 'path', or 'url'")) { karate.log('embed part has no content: ' + e.message); } throw e; }

Prevention

When it happens

Trigger: karate.embed({parts: [{role: 'log', mime: 'text/plain'}]}) — a role-only object with no data/path/url; dynamic parts where the content key was mistyped (e.g. 'bytes' or 'file' instead of data/path).

Common situations: Typos in content keys when building embed maps; parts created from templates where the data field failed to resolve; expecting a role-only entry to act as a header/metadata row.

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/2c4189999352f737. Report an issue: GitHub.

Appendix: source

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

            if (roleObj == null) {
                throw new RuntimeException("embed(): each part needs a 'role'");
            }
            String role = roleObj.toString();
            String mime = pm.get("mime") != null ? pm.get("mime").toString() : null;
            Object url = pm.get("url");
            if (url != null) {
                parts.add(new StepResult.Part(role, mime, url.toString()));
                continue;
            }
            byte[] bytes;
            Object dataObj = pm.get("data");
            Object pathObj = pm.get("path");
            if (dataObj != null) {
                bytes = KarateJsUtils.convertToBytes(unwrapJs(dataObj));
            } else if (pathObj != null) {
                bytes = readPathBytes(pathObj.toString());
            } else {
                throw new RuntimeException("embed(): part '" + role + "' needs 'data', 'path', or 'url'");
            }
            parts.add(new StepResult.Part(role, mime != null ? mime : KarateJsUtils.detectMimeType(bytes), bytes));
        }
        Object meta = map.get("meta");
        @SuppressWarnings("unchecked")
        Map<String, Object> metaMap = meta instanceof Map ? (Map<String, Object>) meta : null;
        return new StepResult.Embed(name, parts, metaMap);
    }

    /** Read an embed part's {@code path} (this:/classpath:/file:/relative) into bytes. */
    private byte[] readPathBytes(String path) {
        try (java.io.InputStream is = getCurrentResource().resolve(path).getStream()) {
            return is.readAllBytes();
        } catch (Exception e) {
            throw new RuntimeException("embed(): failed to read part path '" + path + "': " + e.getMessage(), e);
        }
    }

View on GitHub (pinned to a22eb90246)