karatelabs/karate · error · RuntimeException

RuntimeException(result.message)

Error message

RuntimeException(result.message)

What it means

Match.that() runs a match expression against actual data and, instead of returning a Result, throws a plain RuntimeException carrying the match failure message when the match does not pass. It is the assertion-style entry point of the karate match API: the library throws whenever `result.pass` is false so the failure surfaces immediately with the detailed diff/message produced by the match engine.

Solutions

  1. Print or log result.message from the equivalent Match.execute()/equals result to see the exact diff before fixing the expectation
  2. Correct the expected value to match the actual payload (keys, types, ordering)
  3. If actual data is legitimately variable, loosen the matcher (containsAny, containsOnly, schema-style partial match) instead of strict equality
  4. Ensure the actual input is valid JSON/XML if it came in as a string; use Value.parseIfJsonOrXmlString semantics - plain strings are compared literally

Example fix

// before
Match.that(response.token).isEqualTo("abc123"); // throws on mismatch
// after
Match.that(response.token).isTypeOf("string").isNotNull(); // assert type/presence, or
if (!Match.execute(engine, Match.Type.EQUALS, actual, expected).pass) {
    // handle mismatch programmatically instead of throwing
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (actual == null) { throw new IllegalArgumentException("actual is null before match"); }

Type guard

boolean isParsablePayload(Object o) { return o instanceof java.util.Map || o instanceof java.util.List || o instanceof String; }

Try / catch

try {
    Match.that(actual).isEqualTo(expected);
} catch (RuntimeException e) {
    // e.getMessage() contains the match diff; log and continue or rethrow as assertion failure
    log.warn("match failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling Match.that(actual).isEqualTo(expected) (or any of contains/containsDeep/containsOnly/each*/within etc.) when the actual value does not satisfy the expected condition; the throw happens in the onResult callback registered by that().

Common situations: Test assertions where server responses or transformed payloads differ from expectations: extra/missing JSON keys, wrong types (string vs number), ordering assumptions with containsOnly, or XML/JSON strings passed that fail to parse into the expected shape.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/0cf1d393bf5492cd. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/match/Match.java:63

        EACH_NOT_EQUALS,
        EACH_CONTAINS,
        EACH_NOT_CONTAINS,
        EACH_CONTAINS_ONLY,
        EACH_CONTAINS_ANY,
        EACH_CONTAINS_DEEP,
        WITHIN,
        NOT_WITHIN

    }

    public static Value evaluate(Object actual, Context context, BiConsumer<Context, Result> onResult) {
        return new Value(Value.parseIfJsonOrXmlString(actual), context, onResult);
    }

    public static Value that(Object actual) {
        return new Value(Value.parseIfJsonOrXmlString(actual), null, (context, result) -> {
            if (!result.pass) {
                throw new RuntimeException(result.message);
            }
        });
    }

    public static Result execute(Engine engine, Type matchType, Object actual, Object expected) {
        return execute(engine, matchType, actual, expected, false);
    }

    public static Result execute(Engine engine, Type matchType, Object actual, Object expected, boolean matchEachEmptyAllowed) {
        try (Value actualValue = new Value(actual); Value expectedValue = new Value(expected)) {
            Operation op = new Operation(engine, matchType, actualValue, expectedValue, matchEachEmptyAllowed);
            op.execute();
            return op.getResult();
        }
    }

    public static Result execute(Engine engine, Type matchType, Object actual, Object expected, long memoryThreshold) {
        try (Value actualValue = new Value(actual, null, null, true, memoryThreshold);

View on GitHub (pinned to a22eb90246)