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
- 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.
- Define all variables used in match expressions in Background or at the top of the scenario so they exist at evaluation time.
- Simplify the match expression (split `&&` clauses) to isolate which part throws.
- 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
- Define every variable referenced in match expressions in Background
- Keep match expressions small; move complex logic into def'd helper functions that are themselves tested
- Avoid calling request-derived helpers (paramValue, header) on values that may be absent — guard for null first
- Reproduce the failing expression in a scenario executed by the normal runner to get the full stack trace
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
- start() needs at least one argument: feature path or config…
- start() config requires 'mock' key with feature path
- start() argument must be a string path or config map
- proceed() can only be called within a mock scenario
- proceed() needs a target URL or Host header in request
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)