{"record":{"id":"5c761c12425a6ec8","repo":"stanfordnlp/CoreNLP","slug":"called-remove-before-any-elements-returned","errorCode":null,"errorMessage":"Called remove() before any elements returned","messagePattern":"Called remove\\(\\) before any elements returned","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/logging/Redwood.java","lineNumber":717,"sourceCode":"              break;\n            } else {\n              childIter = childrenIter.next().iterator();\n            }\n          }\n          return !seenHead || (childIter != null && childIter.hasNext());\n        }\n        // -- Next\n        @Override\n        public LogRecordHandler next() {\n          if(!seenHead){ seenHead = true; return head(); }\n          lastReturned = childIter.next();\n          return lastReturned;\n        }\n        // -- Remove\n        @Override\n        public void remove() {\n          if(!seenHead){ throw new IllegalStateException(\"INTERNAL: this shouldn't happen...\"); }\n          if(lastReturned == null){ throw new IllegalStateException(\"Called remove() before any elements returned\"); }\n          if(childOnPrix != null && lastReturned == childOnPrix.head()){\n            childrenIter.remove();\n          } else if(childIter != null){\n            childIter.remove();\n          } else {\n            throw new IllegalStateException(\"INTERNAL: not sure what we're removing\");\n          }\n        }\n      };\n    }\n\n    private static List<Record> append(List<Record> lst, Record toAppend){\n      if(lst == LogRecordHandler.EMPTY){\n        lst = new ArrayList<>();\n      }\n      lst.add(toAppend);\n      return lst;\n    }","sourceCodeStart":699,"sourceCodeEnd":735,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/logging/Redwood.java#L699-L735","documentation":"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().","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nIterator<Redwood.RecordHandlerTree> it = tree.children();\nit.remove(); // throws\n// after\nIterator<Redwood.RecordHandlerTree> it = tree.children();\nwhile (it.hasNext()) {\n  Redwood.RecordHandlerTree t = it.next();\n  if (matches(t)) it.remove();\n}","handlingStrategy":"validation","validationCode":"if (it.hasNext()) {\n  var elem = it.next();\n  if (shouldRemove(elem)) it.remove();\n}","typeGuard":null,"tryCatchPattern":"try {\n  it.remove();\n} catch (IllegalStateException e) {\n  log.warn(\"remove() called before next(): {}\", e.getMessage());\n}","preventionTips":["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"],"tags":["iterator","logging","redwood","contract-violation"],"backgroundTag":"iterator-contract-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}