karatelabs/karate · error
unhandled promise rejection:
Error message
unhandled promise rejection:
What it means
When an async JS chain settles with multiple rejected promises and none is handled, AsyncSupport reports the first rejection (via reportFailure) and logs this warning for each additional unhandled rejection. Karate treats the first unhandled promise rejection as the failure and merely warns about the rest, so developers see 'unhandled promise rejection: <reason>' in logs.
Solutions
- Add a .catch() or try/await around the failing promise in your JS so rejections are handled
- Read the first failure reported — the primary rejection reason is surfaced via reportFailure / engine exception
- If rejections should only warn, configure the engine's asyncRejectionWarnOnly mode
- Fix the underlying cause in the rejection value (HTTP error, assertion, undefined member)
Example fix
// before
karate.call('async-helper'); // returns promise that rejects
// after
return karate.call('async-helper').then(r => r).catch(e => { karate.warn('ignored: ' + e); }); Defensive patterns
Strategy: try-catch
Type guard
// JS: check before using
function isThenable(v) { return v && typeof v.then === 'function'; }
Try / catch
try { await maybeRejecting(); } catch (e) { karate.warn('handled: ' + e); }
Prevention
- Always attach .catch() to promise chains
- Await every promise you create
- Configure asyncRejectionWarnOnly for non-critical flows
- Check logs for secondary rejection warnings after each failure
When it happens
Trigger: JS code in a Scenario (e.g. karate.callSingle with async, custom async functions, promise chains) where one or more promises reject with no .catch/onRejected handler when the async evaluation completes.
Common situations: Forgetting await/catch on a promise inside karate JS; a fetch-like call failing (network, 500) inside an async function; rejecting promises fired after the scenario finished waiting.
Related errors
- unhandled promise rejection
- Promise requires an engine
- Promise requires an active evaluation
- await on a promise that can never settle
- setTimeout: karate is shutting down
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/fd9c5800d23fd8f1.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/AsyncSupport.java:860
* as handled. The first terminal unhandled rejection fails the eval as a
* JS-level error; the rest are logged. Each is reported exactly once.
*/
static void reportUnhandledRejections(Engine engine, AsyncScope scope) {
List<JsPromise> tracked = scope.trackedRejections();
if (tracked.isEmpty()) {
return;
}
List<JsPromise> terminal = new ArrayList<>(1);
for (JsPromise promise : tracked) {
if (!promise.isRejectionHandled() && promise.claimRejectionReport()) {
terminal.add(promise);
}
}
if (terminal.isEmpty()) {
return;
}
for (int i = 1; i < terminal.size(); i++) {
warn(engine, "unhandled promise rejection: " + describe(terminal.get(i).settledValue()));
}
reportFailure(engine, "unhandled promise rejection", terminal.get(0).settledValue());
}
private static void reportFailure(Engine engine, String prefix, Object reason) {
if (engine.asyncRejectionWarnOnly()) {
warn(engine, prefix + ": " + describe(reason));
return;
}
throw asEngineException(prefix, reason);
}
private static void warn(Engine engine, String message) {
logger.warn(message);
java.util.function.Consumer<String> consumer = engine.root().onConsoleLog;
if (consumer != null) {
consumer.accept(message);
}View on GitHub (pinned to a22eb90246)