stanfordnlp/CoreNLP · error · UnsupportedOperationException

Cannot remove pairs from a merged iterator

Error message

Cannot remove pairs from a merged iterator

What it means

The iterator returned by Iterables.merge (which pairs values from two maps in key order) does not implement removal; remove() always throws UnsupportedOperationException. This is a deliberate design because removing from one of two merged sources while keeping the pairing coherent is not supported.

Solutions

  1. Collect keys to remove into a temporary list, then remove them from the underlying map(s) after iteration
  2. Iterate the individual underlying maps directly when removal is needed
  3. Wrap in a new ArrayList or use Iterator over a single map's entrySet
  4. Avoid passing merged iterables to removal-performing utilities

Example fix

// before
for (Pair<K,V> p : Iterables.merge(m1, m2)) {
  it.remove(); // throws
}
// after
List<K> toRemove = new ArrayList<>();
for (Pair<K,V> p : Iterables.merge(m1, m2)) {
  if (shouldRemove(p)) toRemove.add(p.first);
}
toRemove.forEach(k -> { m1.remove(k); m2.remove(k); });
Defensive patterns

Strategy: try-catch

Validate before calling

// removal is never supported here; do not call remove()
// instead collect and remove after iteration
List<K> toRemove = new ArrayList<>();
for (Pair<K,V> p : merged) { if (cond(p)) toRemove.add(p.first); }

Try / catch

try {
  it.remove();
} catch (UnsupportedOperationException e) {
  // fall back: collect targets and remove from underlying maps afterwards
}

Prevention

When it happens

Trigger: Calling iterator.remove() on the iterator obtained from a merged Iterable view, e.g. inside a for-each loop using the remove idiom or from wrapper utilities that call remove().

Common situations: Trying to delete entries while iterating two synchronized maps, passing the merged iterable to a utility that removes as it processes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

          public boolean hasNext() {
            if (!ready) {
              pending = nextPair();
              ready = true;
            }
            return pending != null;
          }

          public Pair<V1, V2> next() {
            if (!ready && !hasNext()) {
              throw new IllegalAccessError("Called next without hasNext");
            }
            ready = false;
            return pending;
          }

          public void remove() {
            throw new UnsupportedOperationException("Cannot remove pairs " +
            "from a merged iterator");
          }

          private Pair<V1,V2> nextPair() {
            V1 nextA = null;
            V2 nextB = null;

            while (iterA.hasNext() && iterB.hasNext()) {
              // increment iterators are null
              if (nextA == null) { nextA = iterA.next(); }
              if (nextB == null) { nextB = iterB.next(); }

              int cmp = comparator.compare(nextA, nextB);
              if (cmp < 0) {
                // iterA too small, increment it next time around
                nextA = null;
              } else if (cmp > 0) {
                // iterB too small, increment it next time around

View on GitHub (pinned to 1b7edd19c4)