karatelabs/karate · error · JsErrorException
Promise requires an active evaluation
Error message
Promise requires an active evaluation
What it means
Karate's JS engine exposes Promise via `scopeOf`, which fetches the engine's current AsyncScope. Promises only make sense while a script evaluation with an async scope is running (microtask queue attached). If `engine.currentScope()` returns null — e.g. Promise is touched outside any evaluation, from another thread, or after evaluation finished — the engine throws this TypeError instead of silently misbehaving.
Solutions
- Ensure Promise usage happens inside a live script evaluation; don't cache or call Promise-related values after eval returns.
- If embedding, run Promise-dependent code on the engine's evaluation thread (or via the engine's async execution entry points) rather than a custom thread.
- Check that no code path nulls out or completes the engine's current scope before the constructor is invoked.
Example fix
// before: host thread invokes JS directly
executor.submit(() -> engine.eval("new Promise(r => r(1))"));
// after: run through the engine's own evaluation/async path
engine.submit("new Promise(r => r(1))"); // engine manages scope Defensive patterns
Strategy: type-guard
Validate before calling
// host-side (Java): only evaluate Promise code inside a live evaluation
if (engine.currentScope() == null) {
throw new IllegalStateException("Promise used outside active evaluation");
} Type guard
function hasActiveScope(engine) { return engine && typeof engine.currentScope === 'function' && engine.currentScope() != null; } Try / catch
try { return evalUserScript(); } catch (e) { if (String(e).includes('Promise requires an active evaluation')) { /* re-run on evaluation thread */ } else { throw e; } } Prevention
- Never call Promise-dependent JS from host threads outside the engine's evaluation lifecycle.
- Keep async JS entry points routed through the engine's own async APIs.
- Document that cached function references into JS must be invoked while the evaluation is alive.
When it happens
Trigger: Calling `new Promise(...)` or `Promise.resolve()/reject()` when no AsyncScope is active: accessing the Promise global outside `eval()` on the engine, invoking the constructor from a non-script thread, or calling it after the evaluation has completed.
Common situations: Embedding karate-js in a host app and invoking JS callbacks on a plain Java thread without pushing a scope; using Promise inside a synchronous one-shot eval that tears down its scope before the constructor runs; racing two engine usages across threads.
Related errors
- Promise requires an engine
- engine is poisoned:
- unhandled promise rejection:
- unhandled promise rejection
- await on a promise that can never settle
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/fa7d1cb4dfdbaa78.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsPromiseConstructor.java:71
defineOwn("race", new JsBuiltinMethod("race", 1, (JsCallable) this::race), METHOD_ATTRS);
defineOwn("any", new JsBuiltinMethod("any", 1, (JsCallable) this::any), METHOD_ATTRS);
}
private static Engine engineOf(Context context) {
Engine engine = context == null ? null : context.getEngine();
if (engine == null) {
engine = Engine.current();
}
if (engine == null) {
throw JsErrorException.typeError("Promise requires an engine");
}
return engine;
}
private static AsyncScope scopeOf(Engine engine) {
AsyncScope scope = engine.currentScope();
if (scope == null) {
throw JsErrorException.typeError("Promise requires an active evaluation");
}
return scope;
}
static JsPromise newPromise(Context context) {
Engine engine = engineOf(context);
AsyncActivation.anyAsync = true;
return new JsPromise(engine, scopeOf(engine));
}
@Override
public Object call(Context context, Object[] args) {
CallInfo callInfo = context.getCallInfo();
if (callInfo == null || !callInfo.constructor) {
throw JsErrorException.typeError("Promise constructor cannot be invoked without 'new'");
}
Object executor = AsyncSupport.arg(args, 0);
if (!(executor instanceof JsCallable callable)) {View on GitHub (pinned to a22eb90246)