karatelabs/karate · warning

scenario match evaluation failed at line

Error message

scenario match evaluation failed at line {}: {} - {}

What it means

While deciding whether a mock scenario applies to an incoming request, MockHandler evaluates the scenario's match expression through the JS engine. If that evaluation throws (bad expression syntax, missing/undefined variable used in the match, engine failure), the exception is caught and logged with this warning and the scenario is treated as not matching — the request moves on to other scenarios and eventually 404.

Solutions

  1. Read the logged line number and expression in the warning; run that expression's logic in a Karate test or JS REPL to see the real exception.
  2. Define all variables used in match expressions in Background or at the top of the scenario so they exist at evaluation time.
  3. Simplify the match expression (split `&&` clauses) to isolate which part throws.
  4. Enable trace logging to see which scenarios are skipped vs which failed evaluation.

Example fix

// before: undefined variable in expression
Scenario: users
  * pathMatches('/users/' + userId)
// after: define it in Background
Background:
  * def userId = 1
Scenario: users
  * pathMatches('/users/' + userId)
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate that variables used in match expressions exist
for (String var : List.of("userId", "expectedStatus")) {
    if (engine.getVariable(var) == null) {
        throw new IllegalStateException("match expression variable missing: " + var);
    }
}

Try / catch

// Wrap mock startup/request handling so eval failures surface immediately
try {
    HttpResponse res = handler.response(request);
} catch (Exception e) {
    logger.error("mock request handling failed", e);
    throw e;
}

Prevention

When it happens

Trigger: A mock feature scenario contains a match expression (e.g. `pathMatches('/x') && paramValue('q') == someVar`) that references an undefined variable, calls a function that throws, or has a runtime error; isMatchingScenario's try block throws Exception and the warn branch fires.

Common situations: Typo in a variable name inside the match expression; using `def`-defined variables only in later scenarios instead of Background; calling helper JS that itself fails (null deref, missing function); copy-paste errors after renaming variables.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/MockHandler.java:482

        String expression = StringUtils.trimToNull(scenario.getName());

        // Empty/null expression means catch-all (always matches)
        if (expression == null) {
            logger.debug("catch-all scenario matched at line: {}", scenario.getLine());
            return true;
        }

        try {
            Object result = engine.eval(expression);
            if (Boolean.TRUE.equals(result)) {
                logger.debug("scenario matched at line {}: {}", scenario.getLine(), expression);
                return true;
            } else {
                logger.trace("scenario skipped at line {}: {}", scenario.getLine(), expression);
                return false;
            }
        } catch (Exception e) {
            logger.warn("scenario match evaluation failed at line {}: {} - {}", scenario.getLine(), expression, e.getMessage());
            return false;
        }
    }

    private HttpResponse executeScenario(ScenarioRuntime runtime, Scenario scenario, HttpRequest request) {
        Engine engine = runtime.getEngine();
        StepExecutor executor = new StepExecutor(runtime);

        // Execute beforeScenario hook before step execution so request-scoped setup can run per-request.
        // A hook exception surfaces as HTTP 500 (same as a step failure) - wrap the hook body in
        // try/catch if you want to suppress errors.
        Exception beforeError = invokeMockHook(config.getBeforeScenario(), "beforeScenario");
        if (beforeError != null) {
            return hookErrorResponse("beforeScenario", beforeError);
        }

        // Execute all steps in the scenario using StepExecutor
        for (Step step : scenario.getSteps()) {

View on GitHub (pinned to a22eb90246)