stanfordnlp/CoreNLP · error · RuntimeException

Filter .next() called with no next

Error message

Filter .next() called with no next

What it means

The anonymous Filter iterator in Iterables.wrap/transform caches one lookahead element. next() calls prepare() to fill that cache; if no element matched the filter predicate, there is nothing to return and the iterator throws rather than returning null.

Solutions

  1. Always guard calls with if (iterator.hasNext()) before next()
  2. Use a for-each loop instead of manual next() calls
  3. Create a fresh iterator per thread instead of sharing
  4. Check the filter predicate if you expect elements but hasNext() is false

Example fix

// before
T v = filteredIterator.next();
// after
if (filteredIterator.hasNext()) {
  T v = filteredIterator.next();
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check before consuming
boolean has = filterIterator.hasNext();
if (has) { T v = filterIterator.next(); }

Type guard

static <T> java.util.Optional<T> nextIfPresent(java.util.Iterator<T> it) {
  return it.hasNext() ? java.util.Optional.of(it.next()) : java.util.Optional.empty();
}

Try / catch

try {
  T v = filterIterator.next();
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("no next")) {
    v = null; // iterator exhausted
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling next() on a Filter iterator after hasNext() returned false, or calling next() repeatedly/concurrently such that the single-slot cache was already consumed (queued == false).

Common situations: Not checking hasNext() in a loop, calling next() twice expecting two elements when only one passed the predicate, or sharing one iterator between threads.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/18999bbf83ba201e. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/util/Iterables.java:84

      final Iterable<T> iterable, final Predicate<T> accept) {

    return new Iterable<T>() {
      public Iterator<T> iterator() {
        return new Iterator<T>() {
          Iterator<T> inner = iterable.iterator();

          boolean queued = false;
          T next = null;

          public boolean hasNext() {
            prepare();
            return queued;
          }

          public T next() {
            prepare();
            if (!queued) {
              throw new RuntimeException("Filter .next() called with no next");
            }
            T rv = next;
            next = null;
            queued = false;
            return rv;
          }

          public void prepare() {
            if (queued) {
              return;
            }

            while (inner.hasNext()) {
              T next = inner.next();
              if (accept.test(next)) {
                this.next = next;
                this.queued = true;
                return;

View on GitHub (pinned to 1b7edd19c4)