karatelabs/karate · error · RuntimeException
invalid json
Error message
invalid json: ${e.getMessage()} What it means
parseLenient() wraps any non-runtime parsing exception (e.g. syntax errors from the underlying JSON parser) into a RuntimeException prefixed with 'invalid json: ' and preserves the cause. The embedded e.getMessage() typically names the syntax problem and position.
Solutions
- Read e.getMessage()/cause to locate the syntax error and fix the JSON source
- Validate the payload with a JSON linter before feeding it in
- If the source is an API, log the raw response body to spot truncation/HTML error pages
Example fix
// before
Json json = Json.of(rawResponse); // 'invalid json: Unexpected token...'
// after
if (!rawResponse.trim().startsWith("{") && !rawResponse.trim().startsWith("[")) { log.error("non-JSON response: " + rawResponse); }
Json json = Json.of(rawResponse); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate syntax with a strict parse in a dry run, or lint the string
if (json != null && json.length() > 0 && (json.startsWith("<") )) throw new IllegalArgumentException("response looks like HTML, not JSON"); Try / catch
try { Object o = Json.parseLenient(s); } catch (RuntimeException e) { if (e.getMessage().startsWith("invalid json:")) { logger.error("parse failed: {} cause={}", e.getMessage(), e.getCause(), e); throw new IllegalArgumentException("bad json payload", e); } throw e; } Prevention
- Always log e.getCause() for parse failures to see the real syntax error
- Validate payloads with a JSON linter in CI for fixture files
- Capture raw response bodies before parsing to debug truncation
When it happens
Trigger: Json.parseLenient("{a:1,}") or Json.of(truncatedJson) — input has content but fails lenient parsing with an underlying parser exception.
Common situations: Truncated API responses, hand-edited JSON with stray commas or unquoted keys beyond lenient tolerance, concatenated JSON fragments.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid json: input is null or blank
- invalid json: not a JSON object or array
- input must not be null
- input string must not be empty or blank
- cannot replace root path $
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/08545ee17a603d67.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/common/Json.java:134
String json = JSONValue.toJSONString(any);
return new Json(JsonPath.parse(json));
}
}
public static Object parseLenient(String json) {
if (json == null || json.isBlank()) {
throw new RuntimeException("invalid json: input is null or blank");
}
try {
Object result = JSONValue.parseKeepingOrder(json);
if (!isMapOrList(result)) {
throw new RuntimeException("invalid json: not a JSON object or array");
}
return result;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("invalid json: " + e.getMessage(), e);
}
}
public static boolean isMapOrList(Object o) {
return o instanceof Map || o instanceof List;
}
public static Object parseStrict(String json) {
return parseStrict(json, false);
}
public static Object parseStrict(String json, boolean keepOrder) {
if (json == null || json.isBlank()) {
throw new RuntimeException("invalid json: input is null or blank");
}
try {
JSONParser parser = new JSONParser(JSONParser.MODE_RFC4627);
if (keepOrder) {View on GitHub (pinned to a22eb90246)