karatelabs/karate · error · RuntimeException
karate.match(String) is not available in this context
Error message
karate.match(String) is not available in this context
What it means
The single-argument string form karate.match("expr") needs a ScenarioRuntime to evaluate the expression (it delegates to the same evaluator as the `match` keyword, resolving variables against the currently executing scenario). The code first tries ScenarioRuntime.currentOrNull(), then the captured getRuntime(); if both are null there is no runtime/variable scope, so KarateJs throws. This typically happens when the karate bridge is used outside a live scenario, such as a standalone mock or utility context.
Solutions
- Move the karate.match(String) call inside a running Scenario (Background or Scenario block) so a current runtime exists.
- Use the two-argument form karate.match(actual, expected) when you have plain values — it does an equals comparison without needing a runtime.
- In mock contexts, resolve needed values into JS variables first and compare with the two-argument form or plain JS.
- If this runs during feature setup, ensure the runtime is initialized before the JS bridge is invoked.
Example fix
// before (mock handler, no scenario runtime)
var ok = karate.match("response == { id: '#number' }");
// after (two-arg form, no runtime needed)
var ok = karate.match(response, { id: '#number' }); Defensive patterns
Strategy: fallback
Validate before calling
// run inside a Scenario; if in a mock, use value-based comparison instead var hasRuntime = typeof scenario !== 'undefined' || karate.match(response, response) !== undefined;
Type guard
function matchAvailable() { try { karate.match('1 == 1'); return true; } catch (e) { return !String(e.message).includes('not available in this context'); } } Try / catch
var result;
try {
result = karate.match('response == { id: \'#number\' }');
} catch (e) {
if (String(e.message).includes('not available in this context')) {
result = karate.match(response, { id: '#number' }); // two-arg fallback
} else { throw e; }
} Prevention
- Use karate.match(String) only inside running Scenarios or Background blocks.
- In mock handlers, prefer the two-argument karate.match(actual, expected) form which needs no runtime.
- Resolve all needed variables into JS values before calling match so the expression string does not depend on scenario scope.
When it happens
Trigger: Calling karate.match('someVar == expected') (one string argument) when no ScenarioRuntime is active and the bridge holds no runtime — e.g. inside a mock-server handler, a karate-config hook without a scenario, or JS evaluated via an engine not attached to a scenario.
Common situations: Mock context: condition closures or JS helpers invoked from a mock server where no scenario is executing. Also setup/teardown hooks or standalone JS evaluation where the caller assumed scenario variables were available.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- karate.call() is not available in this context
- karate.setupOnce() is not available in this context
- karate.callonce() is not available in this context
- karate.callSingle() is not available in this context
- Uint8Array is fixed-size
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/7b4fd69eb2c438e0.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJs.java:677
// Delegate to the same evaluator the `match` keyword uses so both operands
// get identical handling — JsonPath ($-prefixed, wildcards), JSON literals,
// embedded expressions, etc. Reusing StepExecutor.evalMatchString keeps the
// JS API and the keyword from drifting (issue #2894).
//
// The string operands are resolved against the *currently executing*
// scenario, not the scenario where this `karate` bridge was defined. A
// condition closure built in feature A and passed to feature B (via
// `call read('B.feature') filter`) must see B's variables when B invokes
// it — the caller's `response` lives in B's scope, not A's. Using the
// captured getRuntime() (A) surfaced a "ReferenceError: response is not
// defined". Fall back to the captured runtime outside a live scenario
// (e.g. mock context).
ScenarioRuntime rt = ScenarioRuntime.currentOrNull();
if (rt == null) {
rt = getRuntime();
}
if (rt == null) {
throw new RuntimeException("karate.match(String) is not available in this context");
}
String expression = args[0].toString();
Result result = rt.getExecutor().evalMatchString(expression, null);
return result.toMap();
}
};
}
private JavaInvokable call() {
return args -> {
ScenarioRuntime rt = getRuntime();
if (rt == null) {
throw new RuntimeException("karate.call() is not available in this context");
}
if (args.length == 0) {
throw new RuntimeException("karate.call() requires at least one argument (feature path)");
}
// V1 compatible signatures:View on GitHub (pinned to a22eb90246)