karatelabs/karate · error · java.util.NoSuchElementException
NoSuchElementException
Error message
NoSuchElementException
What it means
JsArray's internal KeyValue iterator throws java.util.NoSuchElementException when next() is called after the array's entries are exhausted. The library's own iteration loops always guard with hasNext(); a raw next() past the end means an iteration protocol bug or misuse of the iterator. In JS semantics, calling an exhausted iterator's next() should return {done:true}, never throw.
Solutions
- Guard every next() call with hasNext() before consuming.
- Do not share one iterator across multiple consumers; obtain a fresh iterator per loop.
- If it fires during normal JS for...of, report/check for mid-iteration mutation of the array (splice/length changes) and snapshot before iterating.
- Upgrade karate-js — later versions harden iterator bounds.
Example fix
// before
while (true) { KeyValue kv = it.next(); ... }
// after
while (it.hasNext()) { KeyValue kv = it.next(); ... } Defensive patterns
Strategy: try-catch
Validate before calling
if (arr == null || arr.length === 0) return; // skip iteration entirely
Type guard
boolean canAdvance(Iterator<?> it) { return it != null && it.hasNext(); } Try / catch
try { while (it.hasNext()) { process(it.next()); } } catch (NoSuchElementException e) { log.warn("iterator over-advanced", e); } Prevention
- Always gate next() behind hasNext() or use for-each.
- Never share an iterator across loops or threads.
- Snapshot collections before iterating if they can be mutated.
- Treat NoSuchElementException from an iterator as a caller bug, not a data condition.
When it happens
Trigger: Calling next() on the JsArray entry iterator without checking hasNext() after all elements have been consumed; an engine-internal loop or custom host code advancing the iterator more times than the array has entries.
Common situations: Custom Java host code iterating a Karate JS array; engine bugs during for...of/entries() enumeration after array mutation; concurrent consumption of the same iterator from two loops.
Related errors
- NoSuchElementException
- NoSuchElementException
- NoSuchElementException
- NoSuchElementException
- NoSuchElementException
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3eda910dcbd41f47.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsArray.java:988
if (parseIndex(s.name) >= 0) continue;
if ("length".equals(s.name)) continue;
Object val = ctx != null ? s.read(JsArray.this, ctx)
: (s instanceof DataSlot ds ? ds.value : null);
peeked = new KeyValue(JsArray.this, yieldCount++, s.name, val);
return true;
}
peeked = null;
return false;
}
@Override
public boolean hasNext() {
return peeked != null || advance();
}
@Override
public KeyValue next() {
if (peeked == null && !advance()) throw new NoSuchElementException();
KeyValue kv = peeked;
peeked = null;
return kv;
}
};
}
// =================================================================================================
// Helper methods
// =================================================================================================
static JsArray toArray(Map<String, Object> map) {
List<Object> list = new ArrayList<>();
if (map.containsKey("length")) {
Object length = map.get("length");
if (length instanceof Number) {
int size = ((Number) length).intValue();
for (int i = 0; i < size; i++) {View on GitHub (pinned to a22eb90246)