karatelabs/karate · error · JsErrorException
iterator.next is not a function
Error message
iterator.next is not a function
What it means
In the iterator-object wrapper built from a user-supplied iterator object, fetch() reads the `next` member and requires it to be a callable. If the wrapped object's `next` property is missing, null, or not a function, karate throws this TypeError — the object claimed to be an iterator but does not satisfy the iterator protocol.
Solutions
- Return an object whose `next` is a function: `{ next: function() { return {value: v, done: b}; } }`.
- Do not return a step result object directly as the iterator.
- If next is optional in some states, still provide it (e.g. always return `{done:true}` steps).
Example fix
// before
return { value: 1, done: false };
// after
return { next: function() { return { value: 1, done: false }; } }; Defensive patterns
Strategy: validation
Validate before calling
var it = obj[Symbol.iterator]();
if (it == null || typeof it.next !== 'function') throw new TypeError('object is not an iterator'); Type guard
function isIterator(o) { return o != null && typeof o.next === 'function'; } Try / catch
try { for (var x of obj) { ... } } catch (e) { if (String(e).indexOf('next is not a function') !== -1) { /* use manual index-based loop */ } else { throw e; } } Prevention
- Never return a result-step object where an iterator is expected
- Assign function references (no call parentheses) to next
- Unit-test the iterator object shape before relying on it
When it happens
Trigger: An object returned from Symbol.iterator has no `next` member or `next` is a non-callable value (e.g. a plain data object `{done:false, value:1}` returned instead of `{next: fn}`), consumed via for-of/spread.
Common situations: Confusing an iterator RESULT object ({value,done}) with an ITERATOR object ({next}), returning the wrong shape from a custom Symbol.iterator, or a typo'd member name (`nxt`, `next()` assigned result).
Related errors
- Result of iterator method is not an object
- iterator result is not an object
- Result of the Symbol.iterator method is not an object
- iterator 'return' is not a function
- iterator 'return' result is not an object
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/45b48bebda72001c.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/IterUtils.java:204
}
/**
* Walk an already-constructed iterator object's {@code .next()} method to
* produce a {@link JsIterator}. Shared by {@link #userIterator} (which
* first invokes {@code @@iterator}) and the spec-shaped branch of
* {@link #iteratorFromCallable}.
*/
private static JsIterator iteratorObjectWalker(ObjectLike iterObj, Context context) {
return new JsIterator() {
Object pending;
boolean fetched;
boolean done;
private void fetch() {
if (fetched || done) return;
Object nextFn = iterObj.getMember("next");
if (!(nextFn instanceof JsCallable nextCallable)) {
throw JsErrorException.typeError("iterator.next is not a function");
}
Object step;
if (context instanceof CoreContext cc) {
Object savedThis = cc.thisObject;
cc.thisObject = iterObj;
try {
step = nextCallable.call(cc, EMPTY_ARGS);
} finally {
cc.thisObject = savedThis;
}
} else {
step = nextCallable.call(context, EMPTY_ARGS);
}
if (isJsErrored(context)) { done = true; return; }
if (!(step instanceof ObjectLike stepObj)) {
throw JsErrorException.typeError("iterator result is not an object");
}
if (Terms.isTruthy(readMember(stepObj, "done", context))) {View on GitHub (pinned to a22eb90246)