{"record":{"id":"a8076150cf42dd24","repo":"karatelabs/karate","slug":"promise-resolve-is-not-a-function","errorCode":null,"errorMessage":"Promise resolve is not a function","messagePattern":"Promise resolve is not a function","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsPromiseConstructor.java","lineNumber":314,"sourceCode":"     */\n    private List<JsPromise> collect(Context context, Object[] args, JsPromise result) {\n        Engine engine = engineOf(context);\n        AsyncScope scope = scopeOf(engine);\n        AsyncActivation.anyAsync = true;\n        // NewPromiseCapability(C) rejects a non-constructor `this` with a\n        // synchronous TypeError, ahead of everything the IfAbruptRejectPromise\n        // steps below cover. Outside the try for exactly that reason.\n        ObjectLike receiver = constructorOf(context);\n        Object iterable = AsyncSupport.arg(args, 0);\n        List<JsPromise> promises = new ArrayList<>();\n        JsIterator iter = null;\n        try {\n            // GetPromiseResolve: read `resolve` off the constructor exactly once,\n            // before iteration begins.\n            Object resolveFn = receiver.getMember(\"resolve\", receiver, coreOf(context));\n            checkAbrupt(context);\n            if (!(resolveFn instanceof JsCallable resolveCallable)) {\n                throw JsErrorException.typeError(\"Promise resolve is not a function\");\n            }\n            boolean intrinsic = receiver == this\n                    && resolveFn instanceof JsBuiltinMethod m && m.delegate() == resolveDelegate;\n            iter = IterUtils.getIterator(iterable, context);\n            checkAbrupt(context);\n            while (iter.hasNext()) {\n                Object item = iter.next();\n                checkAbrupt(context);\n                Object next = intrinsic\n                        ? resolveStatic(context, new Object[]{item})\n                        : callWithThis(context, resolveCallable, receiver, new Object[]{item});\n                checkAbrupt(context);\n                promises.add(asPromise(context, engine, scope, next, intrinsic));\n            }\n            // A throw from next() / done / value marks the iterator exhausted and\n            // ends the loop quietly — the pending flag is the real completion.\n            checkAbrupt(context);\n            return promises;","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsPromiseConstructor.java#L296-L332","documentation":"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`.","triggerScenarios":"`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.","commonSituations":"Stubbing Promise.resolve in tests with a plain value; half-implemented Promise subclasses; config code that overwrites Promise members.","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."],"exampleFix":"// before (test stub)\nPromise.resolve = (v) => v; // breaks subclass generics? no — returns value, not thenable... worse: assigned non-callable\n// after\nPromise.resolve = (v) => new Promise((res) => res(v));","handlingStrategy":"validation","validationCode":"function combinatorReady(ctor) {\n  const c = ctor || Promise;\n  return typeof c === 'function' && typeof c.resolve === 'function';\n}","typeGuard":"function hasCallableResolve(ctor) { return ctor != null && typeof ctor.resolve === 'function'; }","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["javascript","promise","static-method"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}