stanfordnlp/CoreNLP · error · IllegalStateException

Call next() before calling remove()!

Error message

Call next() before calling remove()!

What it means

The concatenated iterator's remove() throws IllegalStateException when called before any next() on the current underlying iterator (lastIter is still null). Per the Iterator contract, remove() must follow a next(); this class enforces that explicitly.

Solutions

  1. Only call remove() immediately after a successful next() call.
  2. Track last-read state yourself; never call remove() twice per next().
  3. Collect elements to remove during iteration and remove them from the source after the loop, avoiding iterator remove() entirely.
  4. Use a for-each loop with post-loop source mutation when mutation is needed.

Example fix

// before
Iterator<E> it = concat.iterator();
it.remove(); // IllegalStateException
// after
Iterator<E> it = concat.iterator();
if (it.hasNext()) { E e = it.next(); it.remove(); }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!it.hasNext() && !hasCalledNext) { /* do not call remove() */ }

Type guard

boolean canRemove(Iterator<?> it, boolean lastCallWasNext) { return lastCallWasNext; }

Try / catch

try { it.remove(); } catch (IllegalStateException e) { /* no prior next(); skip removal */ }

Prevention

When it happens

Trigger: Calling remove() as the first operation on a freshly created concatenated iterator, or calling remove() twice in a row without an intervening next().

Common situations: Filtering loops that call remove() before the first element is read; retry/removal logic that lost track of the last next() call.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/util/CollectionUtils.java:932

      public boolean hasNext() {
        return !iters.isEmpty() && iters.get(0).hasNext();
      }
      @Override
      public E next() {
        if (!hasNext()) {
          throw new IllegalArgumentException("Iterator is empty!");
        }
        E next = iters.get(0).next();
        lastIter = iters.get(0);
        while (!iters.isEmpty() && !iters.get(0).hasNext()) {
          iters.remove(0);
        }
        return next;
      }
      @Override
      public void remove() {
        if (lastIter == null) {
          throw new IllegalStateException("Call next() before calling remove()!");
        }
        lastIter.remove();
      }
    };
  }

  public static <E> Iterator<E> iteratorFromEnumerator(final Enumeration<E> lst_) {
    return new Iterator<E>() {
      private final Enumeration<E> lst = lst_;
      @Override
      public boolean hasNext() {
        return lst.hasMoreElements();
      }

      @Override
      public E next() {
        return lst.nextElement();
      }

View on GitHub (pinned to 1b7edd19c4)