karatelabs/karate · error · RuntimeException
params() needs a map argument
Error message
params() needs a map argument
What it means
karate's params() JS helper on HttpRequestBuilder only accepts a single Map argument (matching the `param` keyword semantics: scalar or list values per key). The library throws this RuntimeException when params() is called with no arguments or with a non-Map first argument, because there is no meaningful interpretation of other inputs.
Solutions
- Pass a single map argument: `params({ page: 1, tag: ['x','y'] })`.
- If you have key/value pairs, build a map first: `params({ [k]: v })` or collect into an object.
- Use `param(name, value)` for one-off additions instead of params().
- Wrap dynamic inputs with a check: `if (q && typeof q === 'object' && !Array.isArray(q)) params(q)`.
Example fix
// before
params('page=1&size=10')
// after
params({ page: 1, size: 10 }) Defensive patterns
Strategy: validation
Validate before calling
function safeParams(builder, m) { if (m && typeof m === 'object' && !Array.isArray(m)) builder.params(m); return builder; } Type guard
function isPlainMap(v) { return v != null && typeof v === 'object' && !Array.isArray(v); } Try / catch
try { builder.params(q); } catch (e) { if (('' + e).includes('needs a map argument')) builder.param('raw', String(q)); else throw e; } Prevention
- Always pass a JS object literal to params()
- Never pass URL-encoded query strings — build the map instead
- Use param(name, value) for single dynamic additions
When it happens
Trigger: Calling `params()` with zero arguments, or `params('a=1')`, `params([['a','b']])`, or any string/list/scalar instead of a JS object like `params({a: '1'})`.
Common situations: Porting from older Karate DSL where params took key/value pairs; passing a URL-encoded query string instead of a map; forgetting the argument entirely in a JS `configure` or request block.
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
- read() needs at least one argument
- sysenv() needs the environment-variable name
- sysprop() needs the property name
- readAsBytes() needs at least one argument
- get() needs at least one argument
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/b9cfba8b3778b5f8.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/http/HttpRequestBuilder.java:746
return args -> {
if (args.length < 2) {
throw new RuntimeException("param() needs two arguments");
}
param(args[0] + "", args[1] + "");
return this;
};
}
/**
* The JS-facing plural forms of {@link #param} and {@link #header}. The Java
* {@link #params(Map)} takes a {@code Map<String, List<String>>} and replaces what was
* there, which is awkward to satisfy from JS - these accumulate and accept a scalar or a
* list per key, matching the {@code params} and {@code headers} keywords.
*/
private JavaInvokable params() {
return args -> {
if (args.length == 0 || !(args[0] instanceof Map<?, ?> map)) {
throw new RuntimeException("params() needs a map argument");
}
map.forEach((k, v) -> {
if (v instanceof List<?> list) {
for (Object item : list) {
if (item != null) {
param(k + "", item + "");
}
}
} else if (v != null) {
param(k + "", v + "");
}
});
return this;
};
}
@SuppressWarnings("unchecked")
private JavaInvokable headers() {View on GitHub (pinned to a22eb90246)