stanfordnlp/CoreNLP · error · IllegalStateException
Empty node shouldn't have left branch
Error message
Empty node shouldn't have left branch
What it means
check() treats nodes with a null value ('empty' sentinel nodes) as pure placeholders: such a node must have no children. This IllegalStateException fires when an empty node still has a non-null left child, meaning a deletion or rotation left a half-detached node in the structure. It indicates internal corruption of the interval tree, not bad user data.
Solutions
- Rebuild the IntervalTree from scratch (new tree + re-insert all live intervals) to clear the malformed empty node.
- Do not keep references to removed nodes or call check()/rotate on stale node objects from a previous tree state.
- Serialize access to the tree (single thread or locking); it has no internal synchronization.
- If reproducible via public insert/remove only, file a CoreNLP bug with the minimal operation sequence.
Defensive patterns
Strategy: validation
Validate before calling
// Validate the tree after mutation-heavy phases
assertTreeValid(tree);
void assertTreeValid(IntervalTree<Interval<E>,T> t) {
try { t.check(t.root); }
catch (IllegalStateException e) { throw new RuntimeException("tree corrupt: " + e.getMessage()); }
} Try / catch
try {
tree.remove(interval, value);
} catch (IllegalStateException e) {
tree = rebuildTree(liveIntervals);
} Prevention
- Avoid remove-heavy sequences without re-validating; rebuild periodically if many removals occur.
- Discard references to removed nodes immediately.
- Do not share the tree across threads without synchronization.
- Treat any IllegalStateException from check() as 'rebuild required', not retryable.
When it happens
Trigger: check() (or balance()/rotateUp() which call it) encounters TreeNode.isEmpty() == true whose left field is non-null — typically after remove() left dangling children on an emptied node.
Common situations: Hit during remove-heavy workloads (deleting many intervals then validating); seen when a custom subclass or reflection-based code touched node fields; appeared after an interrupted/concurrent mutation of a shared tree.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Empty node shouldn't have right branch
- max end is not as expected!!!
- node is not on the correct side!!!
- node is not parent's left or right child!!!
- node left parent is not same as node!!!
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/c5db7b55c8bd3e5e.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/util/IntervalTree.java:362
private void adjust(TreeNode<E,T> node) {
adjustUpwards(node, node.parent);
}
public void check() {
check(root);
}
public void check(TreeNode<E,T> treeNode) {
Stack<TreeNode<E,T>> todo = new Stack<>();
todo.add(treeNode);
while (!todo.isEmpty()) {
TreeNode<E,T> node = todo.pop();
if (node == node.parent) {
throw new IllegalStateException("node is same as parent!!!");
}
if (node.isEmpty()) {
if (node.left != null) throw new IllegalStateException("Empty node shouldn't have left branch");
if (node.right != null) throw new IllegalStateException("Empty node shouldn't have right branch");
continue;
}
int leftSize = (node.left != null)? node.left.size:0;
int rightSize = (node.right != null)? node.right.size:0;
E leftMax = (node.left != null)? node.left.maxEnd:null;
E rightMax = (node.right != null)? node.right.maxEnd:null;
E maxEnd = node.value.getInterval().getEnd();
if (leftMax != null && leftMax.compareTo(maxEnd) > 0) {
maxEnd = leftMax;
}
if (rightMax != null && rightMax.compareTo(maxEnd) > 0) {
maxEnd = rightMax;
}
if (!maxEnd.equals(node.maxEnd)) {
throw new IllegalStateException("max end is not as expected!!!");
}
if (node.size != leftSize + rightSize + 1) {View on GitHub (pinned to 1b7edd19c4)