stanfordnlp/CoreNLP · error · IllegalStateException
Called remove() before any elements returned
Error message
Called remove() before any elements returned
What it means
The iterator inside Redwood.RecordHandlerTree throws IllegalStateException("Called remove() before any elements returned") when Iterator.remove() is invoked before next() has returned any element (lastReturned == null). Per the Iterator contract, remove() is only valid after a successful next().
Solutions
- Always call next() before remove(): remove() deletes the element last returned by next()
- Call remove() at most once per next()
- To clear children, iterate with next() and call remove() after each element retrieved
- If you only need to empty the tree, use a dedicated clear/removeChild API instead of raw iterator removal
Example fix
// before
Iterator<Redwood.RecordHandlerTree> it = tree.children();
it.remove(); // throws
// after
Iterator<Redwood.RecordHandlerTree> it = tree.children();
while (it.hasNext()) {
Redwood.RecordHandlerTree t = it.next();
if (matches(t)) it.remove();
} Defensive patterns
Strategy: validation
Validate before calling
if (it.hasNext()) {
var elem = it.next();
if (shouldRemove(elem)) it.remove();
} Try / catch
try {
it.remove();
} catch (IllegalStateException e) {
log.warn("remove() called before next(): {}", e.getMessage());
} Prevention
- Follow the Iterator contract: exactly one remove() per successful next()
- Never call remove() on a fresh iterator
- Use an explicit element-collection loop instead of ad-hoc removal
- Prefer dedicated removal APIs over Iterator.remove when available
When it happens
Trigger: Calling it.remove() on a freshly obtained handler-tree iterator; calling remove() twice in a row without an intervening next(); calling remove() after the last next() threw.
Common situations: Cleanup loops that remove handlers without first advancing the iterator; defensive cleanup code written as `while(it.hasNext()) it.remove();` variants that call remove before next; duplicated remove calls in error paths.
Related errors
- Cannot modify Redwood when within a track
- Cannot nest Redwood threaded environments
- Must capture one of stderr or stdout
- OutputHandler received endTrack() without matching…
- ArrayCoreMap keySet iterator exhausted
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/5c761c12425a6ec8.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/util/logging/Redwood.java:717
break;
} else {
childIter = childrenIter.next().iterator();
}
}
return !seenHead || (childIter != null && childIter.hasNext());
}
// -- Next
@Override
public LogRecordHandler next() {
if(!seenHead){ seenHead = true; return head(); }
lastReturned = childIter.next();
return lastReturned;
}
// -- Remove
@Override
public void remove() {
if(!seenHead){ throw new IllegalStateException("INTERNAL: this shouldn't happen..."); }
if(lastReturned == null){ throw new IllegalStateException("Called remove() before any elements returned"); }
if(childOnPrix != null && lastReturned == childOnPrix.head()){
childrenIter.remove();
} else if(childIter != null){
childIter.remove();
} else {
throw new IllegalStateException("INTERNAL: not sure what we're removing");
}
}
};
}
private static List<Record> append(List<Record> lst, Record toAppend){
if(lst == LogRecordHandler.EMPTY){
lst = new ArrayList<>();
}
lst.add(toAppend);
return lst;
}View on GitHub (pinned to 1b7edd19c4)