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
- Pass a JSON object for bulk set: karate.set({ a: 1, b: 2 }).
- For a single value use two arguments: karate.set('name', value).
- 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
- Use the two-argument form for single values.
- Parse JSON strings with JSON.parse before bulk set.
- Check that the single-arg value is a plain object, not an array or string.
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
- Dynamic expression must return a list or function
- read() needs at least one argument
- sysenv() needs the environment-variable name
- sysprop() needs the property name
- readAsBytes() needs at least one argument
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)