{"record":{"id":"5c174e304d5def19","repo":"karatelabs/karate","slug":"iterator-result-is-not-an-object","errorCode":null,"errorMessage":"iterator result is not an object","messagePattern":"iterator result is not an object","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Interpreter.java","lineNumber":2973,"sourceCode":"                    step = invokeIteratorMethod(iterObj, \"next\", sent, context, true);\n                    if (context.isStopped()) {\n                        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 -> {","sourceCodeStart":2955,"sourceCodeEnd":2991,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Interpreter.java#L2955-L2991","documentation":"During generator-style delegation with iterator 'throw' (e.g. yield* inside a try/catch), Karate invokes the inner iterator's return() method to close it. Per the iterator protocol, if return() is present its result must be an object; the engine throws this TypeError when return() returns a non-object. This mirrors the ECMAScript IteratorClose step.","triggerScenarios":"A custom iterator object used with yield* (or generator delegation) whose return() method returns undefined or a primitive while the outer generator handles a throw() completion.","commonSituations":"Custom iterators with a stub return() that returns nothing; iterators ported from looser engines; generator code with try/finally around yield* delegating to a hand-rolled iterator.","solutions":["Make the iterator's return(value) method return an object (typically `{ done: true, value: value }`)","Convert the inner iterator to a generator so return()/throw() semantics are provided by the engine","If the iterator cannot implement return(), omit the property entirely so the engine takes the no-return-method path instead of validating its result"],"exampleFix":"// before\nreturn() { /* returns undefined */ }\n// after\nreturn(v) { return { done: true, value: v }; }","handlingStrategy":"type-guard","validationCode":"if (it.return && (typeof it.return !== 'function' || !isObj(it.return()))) console.warn('bad return()');","typeGuard":"function hasValidReturnMethod(it) {\n  return !('return' in it) || (typeof it.return === 'function' && typeof it.return() === 'object');\n}","tryCatchPattern":"try { gen.throw(err); } catch (e) { if (String(e).includes('iterator result')) { /* normalize iterator or abandon delegation */ } }","preventionTips":["Implement custom iterators as generators whenever possible","Give return(v) the contract { done: true, value: v }","Exercise generator.throw/return paths in tests, not just next()"],"tags":["javascript","iterator","generator","typeerror"],"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"}