karatelabs/karate · error · RuntimeException

set() with a single argument expects a Map / JSON object

Error message

set() with a single argument expects a Map / JSON object

What it means

When karate.set() is called with exactly one argument, Karate interprets it as a bulk set: the argument must be a Map / JSON object whose entries are variable name/value pairs. If the single argument is not a Map, this error is thrown because there is no other valid single-argument form.

Solutions

  1. Pass a JSON object for bulk set: karate.set({ a: 1, b: 2 }).
  2. For a single value use two arguments: karate.set('name', value).
  3. Parse JSON strings first if you have text, e.g. karate.set(JSON.parse(jsonText)).

Example fix

// before
karate.set('{"a":1}');
// after
karate.set({ a: 1 }); // or karate.set('a', 1)
Defensive patterns

Strategy: type-guard

Validate before calling

if (bulk && (typeof bulk !== 'object' || Array.isArray(bulk))) throw new Error('single-arg set() needs a JSON object');
karate.set(bulk);

Type guard

function isBulkMap(v) { return v != null && typeof v === 'object' && !Array.isArray(v); }
// use: if (isBulkMap(data)) karate.set(data); else karate.set('name', data);

Try / catch

try { karate.set(arg); }
catch (e) { if ((e.message || '').indexOf('expects a Map / JSON object') >= 0) karate.set('value', arg); else throw e; }

Prevention

When it happens

Trigger: karate.set(x) where x is a string, number, array, or null instead of a JSON object; passing a JSON string rather than a parsed object.

Common situations: Migrating from two-argument set() and leaving a stray value; intending bulk assignment but passing JSON text instead of a JS object.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJs.java:584

            }
        }
        return true;
    }

    @SuppressWarnings("unchecked")
    private JavaInvokable set() {
        return args -> {
            // v1 bulk form: karate.set(map) sets each top-level key as a variable.
            // Common pattern is `karate.set(read('classpath:settings.json'))`
            // to load a settings file into scope.
            if (args.length == 1) {
                if (args[0] instanceof Map<?, ?> bulk) {
                    for (Map.Entry<?, ?> e : bulk.entrySet()) {
                        engine.put(e.getKey() + "", e.getValue());
                    }
                    return null;
                }
                throw new RuntimeException("set() with a single argument expects a Map / JSON object");
            }
            if (args.length < 2) {
                throw new RuntimeException("set() needs at least two arguments: name and value");
            }
            String name = args[0] + "";
            if (args.length == 2) {
                // Simple set: karate.set('name', value)
                engine.put(name, args[1]);
            } else {
                // Path set: karate.set('name', 'path', value)
                String path = args[1] + "";
                Object value = args[2];
                Object target = engine.get(name);

                // Check if this is XPath (path starts with /) or target is XML
                if (path.startsWith("/") || target instanceof Node) {
                    // XPath set on XML
                    Document doc;

View on GitHub (pinned to a22eb90246)