karatelabs/karate · error · EngineException

unhandled promise rejection

Error message

unhandled promise rejection: <name>: <jsMessage>

What it means

An asynchronous JS operation (a rejected promise) failed with no handler attached. Depending on `asyncRejectionWarnOnly`, AsyncSupport either logs a warning via `onConsoleLog`/logger or throws an engine exception with message "unhandled promise rejection: <name>: <jsMessage>". This mirrors the browser/Node unhandledrejection behavior inside Karaté's JS engine.

Solutions

  1. Attach `.catch(handler)` or `try { await ... } catch` to every promise that can reject.
  2. Inspect the `<jsMessage>` portion of the message to find the underlying rejection cause.
  3. If warnings are acceptable, configure the engine's asyncRejectionWarnOnly(true) so rejections log instead of aborting.

Example fix

// before
asyncWork(); // rejects unhandled

// after
asyncWork().catch(e => console.log('handled: ' + e));
// or
try { await asyncWork(); } catch (e) { console.log('handled: ' + e); }
Defensive patterns

Strategy: try-catch

Try / catch

// JS: never leave promises unhandled
asyncWork()
  .then(handle)
  .catch(function (e) { console.log('rejection handled: ' + e); });
// or: try { var r = await asyncWork(); } catch (e) { console.log(e); }

Prevention

When it happens

Trigger: A promise created in JS (e.g. via async helpers or karate's async APIs) rejects and no `.catch()`/try-await handles it before the microtask queue drains; reportFailure is invoked with the rejection reason.

Common situations: Forgetting await on an async call whose promise rejects; fire-and-forget promises without catch; network or assertion failures inside async background tasks during scenario execution.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/AsyncSupport.java:870

            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);
        }
    }

    static EngineException asEngineException(String prefix, Object reason) {
        String name = null;
        String jsMessage = null;
        if (reason instanceof ObjectLike obj) {
            if (obj.getMember("name") instanceof String s && !s.isEmpty()) {
                name = s;
            }
            if (obj.getMember("message") instanceof String s) {

View on GitHub (pinned to a22eb90246)