{"record":{"id":"799665835809fc94","repo":"karatelabs/karate","slug":"unknown-operator-operator","errorCode":null,"errorMessage":"Unknown operator: \" + operator","messagePattern":"Unknown operator: \" \\+ operator","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/gherkin/MatchExpression.java","lineNumber":84,"sourceCode":"\n    /**\n     * Converts operator string to Match.Type enum name.\n     * E.g., \"==\" -> \"EQUALS\", \"contains deep\" -> \"CONTAINS_DEEP\"\n     */\n    public String getMatchTypeName() {\n        String base = switch (operator) {\n            case \"==\" -> \"EQUALS\";\n            case \"!=\" -> \"NOT_EQUALS\";\n            case \"contains\" -> \"CONTAINS\";\n            case \"!contains\" -> \"NOT_CONTAINS\";\n            case \"contains deep\" -> \"CONTAINS_DEEP\";\n            case \"contains only\" -> \"CONTAINS_ONLY\";\n            case \"contains only deep\" -> \"CONTAINS_ONLY_DEEP\";\n            case \"contains any\" -> \"CONTAINS_ANY\";\n            case \"contains any deep\" -> \"CONTAINS_ANY_DEEP\";\n            case \"within\" -> \"WITHIN\";\n            case \"!within\" -> \"NOT_WITHIN\";\n            default -> throw new RuntimeException(\"Unknown operator: \" + operator);\n        };\n        return each ? \"EACH_\" + base : base;\n    }\n\n    @Override\n    public String toString() {\n        return (each ? \"each \" : \"\") + actualExpr + \" \" + operator + \" \" + expectedExpr;\n    }\n\n}\n","sourceCodeStart":66,"sourceCodeEnd":95,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/gherkin/MatchExpression.java#L66-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"Programmatic construction of MatchExpression in tests/utilities with invalid operators, or newly added operators not yet covered by the switch.","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"],"exampleFix":"// before\nnew MatchExpression(false, \"x\", \"includes\", \"[1]\");\n// after\nnew MatchExpression(false, \"x\", \"contains\", \"[1]\");","handlingStrategy":"validation","validationCode":"static final Set<String> VALID_OPS = Set.of(\"==\",\"!=\",\"contains\",\"!contains\",\n    \"contains only\",\"contains only deep\",\"contains any\",\"contains any deep\",\n    \"contains deep\",\"within\",\"!within\");\n// validate before constructing MatchExpression\nif (!VALID_OPS.contains(op)) throw new IllegalArgumentException(op);","typeGuard":"static boolean isValidOperator(String op) {\n    return op != null && (op.equals(\"==\") || op.equals(\"!=\") || op.contains(\"contains\") || op.endsWith(\"within\"));\n}","tryCatchPattern":"try {\n    String type = expr.getMatchTypeName();\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Unknown operator\")) {\n        throw new IllegalStateException(\"Unsupported operator: \" + e.getMessage());\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["match-expression","invalid-enum-value","karate-match"],"backgroundTag":"invalid-enum-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}