karatelabs/karate · error · RuntimeException
no such match api:
Error message
no such match api:
What it means
Value.jsGet routes match-API method names (equals, contains, containsDeep, eachContains, within, notWithin, etc.) called on a match Value to a Match.Type. When the requested name is not one of the supported match APIs, the library throws 'no such match api: <name>'. This protects against typos and removed/renamed match verbs.
Solutions
- Check the method name against the supported list in Value.jsGet (equals, contains, notContains, containsDeep, containsOnly, containsAny, each* variants, within, notWithin) and fix the typo
- Consult docs/DESIGN.md or the Match.Type enum for the current set of match APIs in this version
- If migrating from older Karate, rename legacy match verbs to their v2 equivalents
Example fix
// before Match.that(actual).containsOnlyDeep(expected); // no such api // after Match.that(actual).containsDeep(expected); // supported match api
Defensive patterns
Strategy: validation
Validate before calling
java.util.Set<String> VALID = java.util.Set.of("equals","contains","notContains","containsDeep","containsOnly","containsAny","containsOnlyAny","eachEquals","eachNotEquals","eachContains","eachNotContains","eachContainsDeep","eachContainsOnly","eachContainsAny","within","notWithin");
if (!VALID.contains(apiName)) { throw new IllegalArgumentException("unknown match api: " + apiName); } Try / catch
try {
return matchValueJs.getMember(name);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("no such match api:")) {
throw new IllegalStateException("typo in match api: " + e.getMessage());
}
throw e;
} Prevention
- Keep a shared constant list of valid match api names used by dynamic call sites
- Check the Match.Type enum / Value.jsGet switch when upgrading karate versions
- Rely on IDE completion instead of string-built method names where possible
When it happens
Trigger: Calling an unknown method on a match Value from JS, e.g. karate.match(x).containst(...) or a match verb that was renamed between karate versions (e.g. containsOnlyDeep vs containsDeepOnly variants).
Common situations: Typo in a feature/JS match call, migrating older karate scripts whose match API names changed in the karatelabs v2 refactor, or dynamically constructed method names that don't resolve.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid ignore
- Unable to resolve global `this`
- karate-boot.js evaluation failed
- Dynamic expression must return a list or function
- Failed to evaluate dynamic expression
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/447f4379715601a0.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/match/Value.java:447
return switch (name) {
case "equals" -> call(Match.Type.EQUALS);
case "contains" -> call(Match.Type.CONTAINS);
case "containsDeep" -> call(Match.Type.CONTAINS_DEEP);
case "containsOnly" -> call(Match.Type.CONTAINS_ONLY);
case "containsOnlyDeep" -> call(Match.Type.CONTAINS_ONLY_DEEP);
case "containsAny" -> call(Match.Type.CONTAINS_ANY);
case "notEquals" -> call(Match.Type.NOT_EQUALS);
case "eachEquals" -> call(Match.Type.EACH_EQUALS);
case "notContains" -> call(Match.Type.NOT_CONTAINS);
case "eachNotEquals" -> call(Match.Type.EACH_NOT_EQUALS);
case "eachContains" -> call(Match.Type.EACH_CONTAINS);
case "eachNotContains" -> call(Match.Type.EACH_NOT_CONTAINS);
case "eachContainsDeep" -> call(Match.Type.EACH_CONTAINS_DEEP);
case "eachContainsOnly" -> call(Match.Type.EACH_CONTAINS_ONLY);
case "eachContainsAny" -> call(Match.Type.EACH_CONTAINS_ANY);
case "within" -> call(Match.Type.WITHIN);
case "notWithin" -> call(Match.Type.NOT_WITHIN);
default -> throw new RuntimeException("no such match api: " + name);
};
}
}
View on GitHub (pinned to a22eb90246)