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

  1. Read e.getMessage()/cause to locate the syntax error and fix the JSON source
  2. Validate the payload with a JSON linter before feeding it in
  3. 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

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.

Related errors


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)