{"record":{"id":"4ed087ba47bb9853","repo":"karatelabs/karate","slug":"invalid-match-expression-no-operator-found-expression","errorCode":null,"errorMessage":"Invalid match expression, no operator found: \" + expression","messagePattern":"Invalid match expression, no operator found: \" \\+ expression","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/gherkin/GherkinParser.java","lineNumber":746,"sourceCode":"            int tokenEnd = tokenStart + token.length;\n\n            if (operator == null) {\n                // Before operator - this is part of the actual expression\n                if (actualStart < 0) {\n                    actualStart = tokenStart;\n                }\n                actualEnd = tokenEnd;\n            } else {\n                // After operator - this is part of the expected expression\n                if (expectedStart < 0) {\n                    expectedStart = tokenStart;\n                }\n                expectedEnd = tokenEnd;\n            }\n        }\n\n        if (operator == null) {\n            throw new RuntimeException(\"Invalid match expression, no operator found: \" + expression);\n        }\n\n        String actualExpr = actualStart >= 0 ? text.substring(actualStart, actualEnd).trim() : \"\";\n        String expectedExpr = expectedStart >= 0 ? text.substring(expectedStart, expectedEnd).trim() : \"\";\n\n        return new MatchExpression(each, actualExpr, operator, expectedExpr);\n    }\n\n    private static boolean isMatchOperator(String text) {\n        return text.equals(\"==\") || text.equals(\"!=\") ||\n               text.startsWith(\"contains\") || text.equals(\"!contains\") ||\n               text.equals(\"within\") || text.equals(\"!within\");\n    }\n\n}\n","sourceCodeStart":728,"sourceCodeEnd":762,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/gherkin/GherkinParser.java#L728-L762","documentation":"The Gherkin parser's match-expression parser scans a 'match actual expected' expression looking for a recognized operator (==, contains, !contains, etc.). If the scan completes without finding any operator, a RuntimeException is thrown because the expression is structurally invalid and no comparison can be derived; the actual and expected sub-expressions cannot be split.","triggerScenarios":"Passing a match expression string that lacks any recognized operator token to match-expression parsing in GherkinParser — e.g. 'response foo', a typo like 'containsx', or an expression where interpolation produced an empty operator.","commonSituations":"Typos in Karate match syntax in .feature files, copy-paste losing the '==' operator, or constructing match expressions programmatically with interpolated empty strings.","solutions":["Add a valid operator (==, !=, contains, !contains, contains only, contains any, contains deep, within, etc.) to the expression","Fix typos in the operator keyword","Print/log the expression string to spot empty or mangled interpolation"],"exampleFix":"// before\nmatch expression: \"response foo { a: 1 }\"\n// after\nmatch expression: \"response == { a: 1 }\"","handlingStrategy":"validation","validationCode":"// check the expression contains a known operator before parsing\nstatic boolean hasMatchOperator(String expr) {\n    String[] ops = {\"==\", \"!=\", \"contains\", \"!contains\", \"within\", \"!within\"};\n    for (String op : ops) if (expr.contains(op)) return true;\n    return false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    MatchExpression me = parser.parseMatchExpression(text);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Invalid match expression\")) {\n        throw new IllegalArgumentException(\"Fix operator in: \" + text, e);\n    }\n    throw e;\n}","preventionTips":["Always include a recognized operator in match expressions","Lint .feature files for match syntax in CI","Avoid building expressions via string concatenation of possibly-empty parts","Unit-test template-generated match expressions"],"tags":["parser","gherkin","match-expression","syntax"],"backgroundTag":"invalid-argument-format","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"}