karatelabs/karate · error · RuntimeException
karate.call() arg must be a map or list, got
Error message
karate.call() arg must be a map or list, got: <class>
What it means
karate.call() accepts an optional second argument that must be a Map (or null) for a single call, or a List to loop-call. When a single (non-list) call is given any other type — string, number, boolean, function — this RuntimeException is thrown naming the offending Java class.
Solutions
- Wrap scalar arguments in a map: karate.call('path.feature', { id: myId }).
- If you intend per-element calls, pass a JS array (List) instead of a single object.
- Parse JSON strings before passing: JSON.parse(str) or karate.read of a .json file.
- Call the function first and pass its result, not the function reference itself.
Example fix
// before
* def result = karate.call('classpath:user.feature', userId)
// after
* def result = karate.call('classpath:user.feature', { userId: '#(userId)' }) Defensive patterns
Strategy: validation
Validate before calling
// before calling
var arg = karate.get('payload');
if (arg != null && !(arg instanceof Map) && !Array.isArray(arg)) {
karate.log('normalizing arg to map:', typeof arg);
arg = { value: arg };
}
var result = karate.call('classpath:user.feature', arg); Type guard
function isCallArg(a) {
return a == null || a instanceof Map || Array.isArray(a);
}
if (!isCallArg(payload)) payload = { value: payload }; Try / catch
try {
var result = karate.call('classpath:user.feature', payload);
} catch (e) {
if (String(e).indexOf('arg must be a map or list') >= 0) {
result = karate.call('classpath:user.feature', { value: payload });
} else { throw e; }
} Prevention
- Always pass objects (maps) or arrays as call args, never scalars
- Parse JSON strings with JSON.parse before passing
- Invoke functions first; pass results, not function references
- Wrap single scalar IDs in a named field: { id: myId }
When it happens
Trigger: karate.call('path.feature', arg) where arg is a JS primitive (e.g. a string id), a function, or any non-Map non-List value; passing a JSON string instead of a parsed object.
Common situations: Passing a single scalar instead of wrapping it in an object; reading JSON from a file as text and passing it without parsing; a JS function reference typed where its result was intended.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- karate.call() requires a feature context
- boot.ext(' '): does not implement io.karatelabs.core.Ext
- Dynamic expression must return a list or function
- configure 'logging' expects a map, got
- configure 'logging.mask' expects a map, got
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/e0310d39c9adbb16.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java:619
}
// Non-callable JS (e.g. an object/JSON literal file) — return as-is.
return jsTarget;
}
calledFeature = Feature.read(calledResource);
}
// Array-loop call - delegate to shared helper used by the `call` keyword
if (arg instanceof List) {
return executor.callFeatureLoop(calledFeature, (List<?>) arg, tagSelector, lineFilters);
}
// Single call - arg must be a map (or null)
Map<String, Object> callArg = null;
if (arg != null) {
if (arg instanceof Map) {
callArg = (Map<String, Object>) arg;
} else {
throw new RuntimeException("karate.call() arg must be a map or list, got: " + arg.getClass());
}
}
Map<String, Object> resultVars = executor.callFeatureSingle(calledFeature, callArg, tagSelector, lineFilters);
return resultVars != null ? resultVars : new HashMap<>();
}
/**
* Execute karate.callonce() - runs a feature once per FeatureRuntime and caches the result.
* Uses the same cache as the callonce keyword.
* Uses double-check locking to ensure thread-safe execution in parallel scenarios.
*/
public Object executeJsCallOnce(String path, Object arg) {
if (featureRuntime == null) {
throw new RuntimeException("karate.callonce() requires a feature context");
}
// Use the same cache key format as the keyword: "callonce:call read('path')"View on GitHub (pinned to a22eb90246)