karatelabs/karate · error · RuntimeException
karate.fail() called
Error message
karate.fail() called
What it means
karate.fail(message) is an intentional, explicit failure: it unconditionally throws a RuntimeException with the provided message (or a default) so the current scenario is marked failed. This is not a bug — the script author asked for the scenario to stop and fail.
Solutions
- Fix the condition that led to the karate.fail() call being reached
- Read the custom message — it describes why the author failed the scenario
- Remove or gate the karate.fail() call if it should not fire in this environment
Example fix
// before
if (env == 'prod') karate.fail();
// after
if (env == 'prod') karate.skip('not runnable in prod'); Defensive patterns
Strategy: validation
Validate before calling
// JS: gate the fail behind the failing condition and log context
if (cond) { karate.logger.warn('failing because cond, value={}', value); karate.fail('cond was true, value=' + value); } Try / catch
// Not normally caught — karate.fail is meant to fail the scenario.
// If intercepting (e.g. in a wrapper), rethrow:
try { karate.fail('reason'); } finally { /* cleanup */ } Prevention
- Prefer karate.skip() over fail() for environment-based exclusions
- Always pass a descriptive message to karate.fail()
- Search commits for stray debug karate.fail() calls before merging
When it happens
Trigger: Any call to karate.fail() or karate.fail('msg') inside a scenario/JS block executes and always throws. Often seen in conditional logic: if (bad) karate.fail('...').
Common situations: Guard clauses in feature files for unsupported environments; deliberate failure when preconditions are not met; leftover debug calls accidentally committed.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/5d705d76eab4794a.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJsUtils.java:992
throw new RuntimeException("xmlPath() first argument must be XML node or string, but was: " + (xmlObj == null ? "null" : xmlObj.getClass()));
}
try {
return evalXmlPath(doc, path);
} catch (Exception e) {
throw new RuntimeException("xmlPath failed for path: " + path + " - " + e.getMessage(), e);
}
};
}
// ========== Control Flow Utilities ==========
/**
* karate.fail(message) - Explicitly fail the scenario with a message.
*/
static JavaInvokable fail() {
return args -> {
String message = args.length > 0 && args[0] != null ? args[0].toString() : "karate.fail() called";
throw new RuntimeException(message);
};
}
// ========== Type Conversion Utilities (Invokable) ==========
/**
* karate.toJava() - Deprecated no-op for V1 compatibility.
* In V2, JavaScript arrays work directly with Java, so this is unnecessary.
*/
static JavaInvokable toJava() {
return args -> {
logger.warn("karate.toJava() is deprecated and a no-op in V2 - JavaScript arrays work directly with Java");
if (args.length < 1) {
return null;
}
return args[0]; // no-op, just return the input
};
}View on GitHub (pinned to a22eb90246)