karatelabs/karate · warning · java.util.NoSuchElementException

NoSuchElementException

Error message

NoSuchElementException

What it means

IterUtils returns a degenerate iterator for empty/unusable iterables whose next() unconditionally throws java.util.NoSuchElementException. hasNext() always returns false, so hitting this means code called next() without consulting hasNext() — the iterator is only safe when the empty check is honored.

Solutions

  1. Check hasNext() before every next() call
  2. Verify the source collection — if it should not be empty, fix why it is empty upstream
  3. In JS, iterate with for...of or Array/Map helpers instead of manual next() calls
  4. If wrapping IterUtils output, return done results instead of throwing

Example fix

// before
Iterator<?> it = IterUtils.iterator(emptyList);
Object v = it.next(); // NoSuchElementException
// after
Iterator<?> it = IterUtils.iterator(emptyList);
Object v = it.hasNext() ? it.next() : null;
Defensive patterns

Strategy: type-guard

Validate before calling

if (list == null || list.isEmpty()) return; // skip iteration

Type guard

boolean hasNextSafe(Iterator<?> it) { return it != null && it.hasNext(); }

Try / catch

try {
  value = it.next();
} catch (NoSuchElementException e) {
  value = null; // iterator exhausted or empty sentinel
}

Prevention

When it happens

Trigger: Calling next() on the sentinel empty iterator returned by IterUtils (e.g. iterating a null/empty collection, or JS for-of/Iterator protocol consumers that call next() without a proper done result).

Common situations: JS loops over an empty Java collection converted via IterUtils; custom iteration code that assumes at least one element; a JS engine calling next() on an exhausted/empty iterator with a protocol mismatch.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/IterUtils.java:509

    private static final Object[] EMPTY_ARGS = new Object[0];

    /**
     * Yields nothing; IteratorClose stays the default no-op. Returned when
     * iterator acquisition itself completed abruptly (the cooperative
     * stop-flag is set), so callers unwind without further calls into user
     * code and the pending error propagates unmodified.
     */
    private static JsIterator exhaustedIterator() {
        return new JsIterator() {
            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public Object next() {
                throw new NoSuchElementException();
            }
        };
    }

    private static boolean isJsErrored(Context context) {
        return context instanceof CoreContext cc && cc.isError();
    }

    /** Reads a slot, invoking an accessor getter if present (so user iterators with
     *  `get value() { ... }` semantics — common in spec tests — surface their getter
     *  errors at iteration time). Routes through the receiver-aware
     *  {@link ObjectLike#getMember(String, Object, CoreContext)}; a non-CoreContext
     *  context yields {@code undefined} for accessor descriptors (no thread for
     *  thisObject swap). */
    /** True when {@code name} exists anywhere on {@code obj}'s prototype chain. */
    private static boolean hasProperty(ObjectLike obj, String name) {
        for (ObjectLike o = obj; o != null; o = o.getPrototype()) {
            if (o.isOwnProperty(name)) {

View on GitHub (pinned to a22eb90246)