{"record":{"id":"61d6cd35eff3822c","repo":"karatelabs/karate","slug":"the-iterator-does-not-provide-a-throw-method","errorCode":null,"errorMessage":"The iterator does not provide a 'throw' method","messagePattern":"The iterator does not provide a 'throw' method","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Interpreter.java","lineNumber":2975,"sourceCode":"                        return Terms.UNDEFINED;\n                    }\n                }\n                case THROW -> {\n                    Object throwFn = iterObj.getMember(\"throw\", iterObj, context);\n                    if (context.isStopped()) {\n                        return Terms.UNDEFINED; // a throwing `throw` getter wins outright\n                    }\n                    if (throwFn == null || throwFn == Terms.UNDEFINED) {\n                        // ABSENT throw: close the delegate (validating\n                        // return()'s result when present), then TypeError\n                        Object closed = invokeIteratorMethod(iterObj, \"return\", null, context, false);\n                        if (context.isStopped()) {\n                            return Terms.UNDEFINED;\n                        }\n                        if (closed != null && !(closed instanceof ObjectLike)) {\n                            throw JsErrorException.typeError(\"iterator result is not an object\");\n                        }\n                        throw JsErrorException.typeError(\n                                \"The iterator does not provide a 'throw' method\");\n                    }\n                    if (!(throwFn instanceof JsCallable throwCallable)) {\n                        // GetMethod: a PRESENT non-callable throws immediately,\n                        // with no iterator close\n                        throw JsErrorException.typeError(\"iterator.throw is not a function\");\n                    }\n                    step = invokeIteratorCallable(iterObj, throwCallable, sent, context);\n                    if (context.isStopped()) {\n                        return Terms.UNDEFINED;\n                    }\n                    if (!(step instanceof ObjectLike)) {\n                        throw JsErrorException.typeError(\"iterator result is not an object\");\n                    }\n                }\n                case RETURN -> {\n                    Object returned = invokeIteratorMethod(iterObj, \"return\", sent, context, false);\n                    if (context.isStopped()) {","sourceCodeStart":2957,"sourceCodeEnd":2993,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Interpreter.java#L2957-L2993","documentation":"When a throw completion is sent into a delegated iterator (yield* with .throw()), and the iterator object has no 'throw' method at all, the engine reports that the iterator does not provide a 'throw' method. This is the ECMAScript-specified message for the yield* delegation path; it follows IteratorClose of the inner iterator first.","triggerScenarios":"Calling generator.throw(err) on a generator that is currently suspended inside a yield* delegating to a custom iterator lacking a throw method, or for-of/iterator code paths that forward throw completions to a plain iterator object.","commonSituations":"Hand-rolled iterator objects (only next(), maybe return()) delegated to via yield*; consumers expecting full generator protocol from plain iterators; mixing generator throw with arrays wrapped through the generic iterator adapter.","solutions":["Add a throw method to the custom iterator object","Replace the hand-rolled iterator with a generator function, which provides next/return/throw automatically","Avoid calling .throw() on the outer generator while it is delegated into a plain iterator"],"exampleFix":"// before\nconst it = { next() { ... } }; // no throw\n// after\nfunction* gen() { ... } // generator supplies throw/return","handlingStrategy":"type-guard","validationCode":"if (typeof innerIterator.throw !== 'function') { /* avoid delegating throw into this iterator */ }","typeGuard":"function supportsThrow(it) { return it != null && typeof it.throw === 'function'; }","tryCatchPattern":"try { gen.throw(e); } catch (err) { if (String(err).includes(\"does not provide a 'throw'\")) { gen.return(undefined); /* close cleanly instead */ } }","preventionTips":["Only delegate throw into generators or iterators known to implement throw()","Close the outer generator with .return() when the inner iterator lacks throw","Wrap inner iterators with a generator adapter that adds default throw/return"],"tags":["javascript","iterator","generator","typeerror"],"backgroundTag":"unsupported-operation","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}