{"record":{"id":"a730357fe6b02fbb","repo":"karatelabs/karate","slug":"iterator-throw-is-not-a-function","errorCode":null,"errorMessage":"iterator.throw is not a function","messagePattern":"iterator\\.throw is not a function","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Interpreter.java","lineNumber":2981,"sourceCode":"                        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()) {\n                        return Terms.UNDEFINED;\n                    }\n                    if (returned == null) {\n                        // no return method: propagate the return completion\n                        context.stopAndReturn(sent);\n                        return Terms.UNDEFINED;","sourceCodeStart":2963,"sourceCodeEnd":2999,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Interpreter.java#L2963-L2999","documentation":"When a throw completion is delegated to an inner iterator and its 'throw' property is present but not callable (e.g. null, a number, an object), the engine throws 'iterator.throw is not a function'. Per GetMethod semantics this throws immediately without closing the iterator.","triggerScenarios":"A custom iterator object has a non-function 'throw' property (typo, wrong assignment, or a placeholder value) and the consumer calls generator.throw() while suspended in yield* over that iterator.","commonSituations":"Assigning throw: true or throw: null as a placeholder; property-name collisions overwriting the method; partial iterator implementations copied from examples.","solutions":["Ensure 'throw' is a function on the iterator object, or remove the property entirely so the missing-method path applies","Convert the iterator to a generator to inherit correct throw semantics","Check for accidental overwrites of iterator methods when extending the object"],"exampleFix":"// before\nconst it = { next() {...}, throw: null };\n// after\nconst it = { next() {...}, throw(e) { return { done: true }; } };","handlingStrategy":"validation","validationCode":"if ('throw' in it && typeof it.throw !== 'function') delete it.throw; // or fix to a function","typeGuard":"function isCallableProp(obj, name) { return obj == null || !(name in obj) || typeof obj[name] === 'function'; }","tryCatchPattern":"try { gen.throw(e); } catch (err) { if (String(err).includes('iterator.throw is not a function')) { /* repair iterator then rethrow */ } }","preventionTips":["Never use placeholder non-function values for method names","Avoid data fields named next/return/throw on iterator objects","Use generators to eliminate manual protocol maintenance"],"tags":["javascript","iterator","typeerror","generator"],"backgroundTag":"type-mismatch","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"}