karatelabs/karate · error · JsErrorException
Promise resolve is not a function
Error message
Promise resolve is not a function
What it means
The spec's PerformPromiseAll reads the `resolve` static off the constructor and requires it to be callable before iterating the input. Karate reads `resolve` once via `getMember` and throws this TypeError when the receiver's `resolve` is missing or not a JsCallable — i.e. the combinator's `this` constructor doesn't provide a usable `resolve`.
Solutions
- Restore `Promise.resolve` to a function (reload/refresh the engine context if it was patched).
- When rebinding combinators, pass a class that defines a callable static `resolve`.
- Guard: `if (typeof Promise.resolve !== 'function') throw ...` before using combinators.
Example fix
// before (test stub) Promise.resolve = (v) => v; // breaks subclass generics? no — returns value, not thenable... worse: assigned non-callable // after Promise.resolve = (v) => new Promise((res) => res(v));
Defensive patterns
Strategy: validation
Validate before calling
function combinatorReady(ctor) {
const c = ctor || Promise;
return typeof c === 'function' && typeof c.resolve === 'function';
} Type guard
function hasCallableResolve(ctor) { return ctor != null && typeof ctor.resolve === 'function'; } Try / catch
try { return Receiver.all(iterable); } catch (e) { if (e instanceof TypeError && /resolve is not a function/.test(e.message)) return Promise.all(iterable); throw e; } Prevention
- Don't stub or overwrite Promise.resolve with non-function values.
- Subclasses used as combinator receivers must define a callable static resolve.
- Run a smoke test that calls Promise.all([...]) at engine startup.
When it happens
Trigger: `Promise.all.call(SomeClass, iterable)` where SomeClass has no static `resolve` or a non-function `resolve`; deleting/overwriting `Promise.resolve` with a non-function before calling a combinator.
Common situations: Stubbing Promise.resolve in tests with a plain value; half-implemented Promise subclasses; config code that overwrites Promise members.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- <JS rejection reason>
- Method Promise.prototype called on incompatible receiver
- Promise combinator called on a non-constructor
- Promise constructor cannot be invoked without 'new'
- Promise requires an active evaluation
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/a8076150cf42dd24.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsPromiseConstructor.java:314
*/
private List<JsPromise> collect(Context context, Object[] args, JsPromise result) {
Engine engine = engineOf(context);
AsyncScope scope = scopeOf(engine);
AsyncActivation.anyAsync = true;
// NewPromiseCapability(C) rejects a non-constructor `this` with a
// synchronous TypeError, ahead of everything the IfAbruptRejectPromise
// steps below cover. Outside the try for exactly that reason.
ObjectLike receiver = constructorOf(context);
Object iterable = AsyncSupport.arg(args, 0);
List<JsPromise> promises = new ArrayList<>();
JsIterator iter = null;
try {
// GetPromiseResolve: read `resolve` off the constructor exactly once,
// before iteration begins.
Object resolveFn = receiver.getMember("resolve", receiver, coreOf(context));
checkAbrupt(context);
if (!(resolveFn instanceof JsCallable resolveCallable)) {
throw JsErrorException.typeError("Promise resolve is not a function");
}
boolean intrinsic = receiver == this
&& resolveFn instanceof JsBuiltinMethod m && m.delegate() == resolveDelegate;
iter = IterUtils.getIterator(iterable, context);
checkAbrupt(context);
while (iter.hasNext()) {
Object item = iter.next();
checkAbrupt(context);
Object next = intrinsic
? resolveStatic(context, new Object[]{item})
: callWithThis(context, resolveCallable, receiver, new Object[]{item});
checkAbrupt(context);
promises.add(asPromise(context, engine, scope, next, intrinsic));
}
// A throw from next() / done / value marks the iterator exhausted and
// ends the loop quietly — the pending flag is the real completion.
checkAbrupt(context);
return promises;View on GitHub (pinned to a22eb90246)