karatelabs/karate · error · RuntimeException
configure 'logging' expects a map, got
Error message
configure 'logging' expects a map, got: ${value == null ? "null" : value.getClass().getName()} What it means
The 'configure logging' key must be assigned a Map (e.g. 'configure logging = { report: "info", mask: {...} }'). If the assigned value is null or any non-map type (String, number, boolean), configureLogging throws with the actual type name.
Solutions
- Change the value to a map, e.g. 'configure logging = { report: "info" }'
- If you meant to set the report level, put it under the 'report' key inside the map
- Check karate-config.js for variable interpolation that may produce null or a string
Example fix
// before
* configure logging = 'info'
// after
* configure logging = { report: 'info' } Defensive patterns
Strategy: type-guard
Validate before calling
var isLoggingMap = function (v) { return v !== null && typeof v === 'object' && !(v instanceof Array); }; Type guard
function isPlainObject(v) { return v != null && v.getClass && java.util.Map.class.isInstance(v); } Try / catch
try { karate.configure('logging', v); } catch (RuntimeException e) { if (e.getMessage().contains("configure 'logging' expects a map")) { log.error('logging must be an object/map, got: ' + typeof v); } throw e; } Prevention
- Always assign an object literal to configure logging
- Put level values under the report key inside the map
- Validate generated config objects in karate-config.js before use
When it happens
Trigger: Writing 'configure logging = "info"' (string instead of map), 'configure logging = true', or 'configure logging = null' in a feature file or karate-config.js.
Common situations: Users assuming logging takes a level string directly (the level goes inside the map under 'report'); porting from other frameworks where a simple value is expected; JS code assigning a non-object to logging.
Related errors
- configure 'logging.mask' expects a map, got
- unexpected 'configure' key
- 'configure report = ' is no longer supported; use…
- Class must implement RunListenerFactory or RunListener
- Invalid callbackPort type: " + portValue.getClass()
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/33df2d917e327541.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/KarateConfig.java:623
if (map.containsKey("logLevel")) {
throw new RuntimeException(
"'configure report = { logLevel: ... }' is no longer supported; use "
+ "'configure logging = { report: \"info\" }' instead "
+ "(see docs/MIGRATION_GUIDE.md#logging)");
}
if (map.containsKey("showLog")) {
this.report.put("showLog", toBoolean(map.get("showLog")));
}
if (map.containsKey("showAllSteps")) {
this.report.put("showAllSteps", toBoolean(map.get("showAllSteps")));
}
}
}
@SuppressWarnings("unchecked")
private void configureLogging(Object value) {
if (!(value instanceof Map<?, ?> raw)) {
throw new RuntimeException("configure 'logging' expects a map, got: "
+ (value == null ? "null" : value.getClass().getName()));
}
Map<String, Object> map = (Map<String, Object>) raw;
if (map.containsKey("report")) {
String levelStr = toString(map.get("report"));
this.logging.put("report", levelStr);
LogContext.setLogLevel(LogLevel.valueOf(levelStr.toUpperCase()));
}
if (map.containsKey("console")) {
String levelStr = toString(map.get("console"));
this.logging.put("console", levelStr);
LogContext.setRuntimeLogLevel(levelStr);
}
if (map.containsKey("pretty")) {
boolean pretty = toBoolean(map.get("pretty"));
this.logging.put("pretty", pretty);
LogContext.get().setPretty(pretty);
}View on GitHub (pinned to a22eb90246)