karatelabs/karate · error · java.util.NoSuchElementException

NoSuchElementException

Error message

NoSuchElementException

What it means

This NoSuchElementException is thrown by a JS Set iterator's next() when the iterator has been exhausted: cursor has advanced past the number of elements in the set. Karate's JsSetPrototype wraps a LinkedHashSet-backed structure and its iterator deliberately throws instead of returning undefined, matching Java Iterator semantics. It usually means the iterator's hasNext() was not respected or next() was called manually one time too many.

Solutions

  1. Guard every next() call with hasNext() before consuming the iterator.
  2. Prefer iteration helpers (values()/entries() or for...of style loops) over manual next() calls.
  3. If an iterator must be reused, obtain a fresh iterator via iterator() instead of reusing an exhausted one.

Example fix

// before
var it = mySet.iterator();
while (true) { var v = it.next(); }
// after
var it = mySet.iterator();
while (it.hasNext()) { var v = it.next(); }
Defensive patterns

Strategy: type-guard

Validate before calling

// before consuming
if (it.hasNext()) { var v = it.next(); }

Type guard

function safeNext(it) { return it.hasNext() ? it.next() : null; }

Try / catch

// rarely needed; guard instead of catching
try { v = it.next(); } catch (e) { /* iterator exhausted */ v = null; }

Prevention

When it happens

Trigger: Calling next() on a Set iterator when hasNext() is false — e.g. from values or entries iteration paths when a caller invokes iterator.next() an extra time after consuming all elements.

Common situations: JS code doing `var it = mySet.iterator(); while (true) { it.next(); }` without checking hasNext(); host code re-using a spent iterator; off-by-one loops using the set's size incorrectly.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/3f814b60f971941a. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsSetPrototype.java:413

    }

    /**
     * @param entries when {@code true}, yields {@code [v, v]} pairs (matching Map.entries
     *                shape); when {@code false}, yields {@code v} alone.
     */
    private static JsIterator setIterator(JsSet s, boolean entries) {
        return new JsIterator() {
            int cursor = 0;

            @Override
            public boolean hasNext() {
                return cursor < s.elements.size();
            }

            @Override
            public Object next() {
                if (cursor >= s.elements.size()) {
                    throw new NoSuchElementException();
                }
                Iterator<Object> it = s.elements.keySet().iterator();
                for (int i = 0; i < cursor; i++) it.next();
                Object v = it.next();
                cursor++;
                if (entries) {
                    List<Object> pair = new ArrayList<>(2);
                    pair.add(v);
                    pair.add(v);
                    return pair;
                }
                return v;
            }
        };
    }

}

View on GitHub (pinned to a22eb90246)