{"record":{"id":"52756a46cb0767c3","repo":"karatelabs/karate","slug":"iterator-result-is-not-an-object-iterutils","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/IterUtils.java","lineNumber":220,"sourceCode":"                Object nextFn = iterObj.getMember(\"next\");\n                if (!(nextFn instanceof JsCallable nextCallable)) {\n                    throw JsErrorException.typeError(\"iterator.next is not a function\");\n                }\n                Object step;\n                if (context instanceof CoreContext cc) {\n                    Object savedThis = cc.thisObject;\n                    cc.thisObject = iterObj;\n                    try {\n                        step = nextCallable.call(cc, EMPTY_ARGS);\n                    } finally {\n                        cc.thisObject = savedThis;\n                    }\n                } else {\n                    step = nextCallable.call(context, EMPTY_ARGS);\n                }\n                if (isJsErrored(context)) { done = true; return; }\n                if (!(step instanceof ObjectLike stepObj)) {\n                    throw JsErrorException.typeError(\"iterator result is not an object\");\n                }\n                if (Terms.isTruthy(readMember(stepObj, \"done\", context))) {\n                    done = true;\n                    return;\n                }\n                if (isJsErrored(context)) { done = true; return; }\n                pending = readMember(stepObj, \"value\", context);\n                if (pending == null && !hasProperty(stepObj, \"value\")) {\n                    // A step result with no `value` member reads as undefined\n                    // (spec GetV) — the distinction matters downstream, where\n                    // a destructuring default fires on undefined but not null.\n                    pending = Terms.UNDEFINED;\n                }\n                if (isJsErrored(context)) { done = true; return; }\n                fetched = true;\n            }\n\n            @Override","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/IterUtils.java#L202-L238","documentation":"After calling `next()` on a user-supplied iterator object, karate requires the returned step to be an object (per spec IteratorStep, which does ToObject on the result). If next() returns a primitive, null, or undefined, this TypeError is thrown.","triggerScenarios":"A custom iterator's next() function returns a bare value like `return i++` or `return null` instead of `{value: x, done: bool}`, and the iterator is consumed by for-of, spread, or Array.from.","commonSituations":"Beginner iterator implementations returning values directly, refactored next() that dropped the result-object wrapper, or next() delegating to a function that returns a primitive.","solutions":["Always return a result object from next(): `return { value: v, done: false }`.","Wrap primitive returns: `return { value: compute(), done: false };`.","Ensure the terminal call also returns an object: `return { done: true };`."],"exampleFix":"// before\nnext: function() { return items[i++]; }\n// after\nnext: function() { return i < items.length ? { value: items[i++], done: false } : { done: true }; }","handlingStrategy":"type-guard","validationCode":"var step = it.next();\nif (step == null || typeof step !== 'object') throw new TypeError('next() must return an object');","typeGuard":"function isIteratorStep(s) { return s != null && typeof s === 'object' && typeof s.done === 'boolean'; }","tryCatchPattern":"try { var step = it.next(); consume(step.value); } catch (e) { if (String(e).indexOf('not an object') !== -1) { /* treat iterator as broken */ } else { throw e; } }","preventionTips":["next() must always return {value, done} objects, including at exhaustion","Avoid returning raw values from helper functions delegated to by next()","Test the full pull cycle with Array.from"],"tags":["javascript","iterator-protocol","typeerror"],"backgroundTag":"unexpected-response-shape","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"}