karatelabs/karate · error · RuntimeException
Unknown operator: " + operator
Error message
Unknown operator: " + operator
What it means
MatchExpression.getMatchTypeName() maps a parsed operator string to its internal enum-style name (e.g. 'contains' -> CONTAINS, 'within' -> WITHIN) via a switch. Any operator value not in the recognized set falls into the default branch and throws a RuntimeException. In practice this indicates the operator string was not produced by the normal parser path or an unsupported operator was constructed manually.
Solutions
- Use one of the supported operators: ==, !=, contains, !contains, contains only, contains any, contains deep, within, !within (and 'each' variants)
- Fix the operator string passed when constructing MatchExpression
- If a new operator is needed, extend both the parser and this switch
Example fix
// before new MatchExpression(false, "x", "includes", "[1]"); // after new MatchExpression(false, "x", "contains", "[1]");
Defensive patterns
Strategy: validation
Validate before calling
static final Set<String> VALID_OPS = Set.of("==","!=","contains","!contains",
"contains only","contains only deep","contains any","contains any deep",
"contains deep","within","!within");
// validate before constructing MatchExpression
if (!VALID_OPS.contains(op)) throw new IllegalArgumentException(op); Type guard
static boolean isValidOperator(String op) {
return op != null && (op.equals("==") || op.equals("!=") || op.contains("contains") || op.endsWith("within"));
} Try / catch
try {
String type = expr.getMatchTypeName();
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Unknown operator")) {
throw new IllegalStateException("Unsupported operator: " + e.getMessage());
}
throw e;
} Prevention
- Only construct MatchExpression via the GherkinParser, not manually
- Keep the parser's operator list and the switch in sync when adding operators
- Use constants/enums for operator strings instead of raw literals
- Add a test iterating all supported operators through getMatchTypeName
When it happens
Trigger: Calling getMatchTypeName() (directly or via matchType()) on a MatchExpression whose operator field holds an unrecognized string — e.g. hand-constructing a MatchExpression with a typo like 'includes' or an operator not in the supported set.
Common situations: Programmatic construction of MatchExpression in tests/utilities with invalid operators, or newly added operators not yet covered by the switch.
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
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/799665835809fc94.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/gherkin/MatchExpression.java:84
/**
* Converts operator string to Match.Type enum name.
* E.g., "==" -> "EQUALS", "contains deep" -> "CONTAINS_DEEP"
*/
public String getMatchTypeName() {
String base = switch (operator) {
case "==" -> "EQUALS";
case "!=" -> "NOT_EQUALS";
case "contains" -> "CONTAINS";
case "!contains" -> "NOT_CONTAINS";
case "contains deep" -> "CONTAINS_DEEP";
case "contains only" -> "CONTAINS_ONLY";
case "contains only deep" -> "CONTAINS_ONLY_DEEP";
case "contains any" -> "CONTAINS_ANY";
case "contains any deep" -> "CONTAINS_ANY_DEEP";
case "within" -> "WITHIN";
case "!within" -> "NOT_WITHIN";
default -> throw new RuntimeException("Unknown operator: " + operator);
};
return each ? "EACH_" + base : base;
}
@Override
public String toString() {
return (each ? "each " : "") + actualExpr + " " + operator + " " + expectedExpr;
}
}
View on GitHub (pinned to a22eb90246)