stanfordnlp/CoreNLP · error · IllegalStateException
Empty node shouldn't have right branch
Error message
Empty node shouldn't have right branch
What it means
The right-child mirror of the 'Empty node shouldn't have left branch' check: an empty (null-valued) sentinel TreeNode must be a leaf, and check() throws this IllegalStateException when an empty node still has a non-null right child. It signals structural corruption produced by the tree's own update/removal or rotation code, not by user data.
Solutions
- Reconstruct the tree: create a fresh IntervalTree and re-insert all intervals.
- Avoid mutating or persisting TreeNode internals; only use the public insert/remove/overlap API.
- Ensure single-threaded or externally synchronized access to the tree.
- Reproduce with a minimal insert/remove sequence and report upstream if it occurs without external interference.
Defensive patterns
Strategy: validation
Validate before calling
// Detect corruption right after removals
try {
tree.check(tree.root);
valid = true;
} catch (IllegalStateException e) {
valid = false; // empty node still carries a branch -> rebuild
} Try / catch
try {
tree.check(tree.root);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Empty node")) { tree = rebuildTree(intervals); }
} Prevention
- After batch removals, run check() once in tests to confirm structural health.
- Use only the public API for deletions.
- Avoid concurrent mutation; the tree has no internal locking.
- Maintain an authoritative list of intervals for cheap rebuilds.
When it happens
Trigger: check() (directly or via balance()/rotateUp()) pops a node where isEmpty() is true but node.right != null — commonly after remove() or a rotation mis-assigned the right pointer of an emptied node.
Common situations: Encountered while debugging interval deletion in CoreNLP; after concurrent unsynchronized insert/remove on a shared tree; after external code or deserialization replaced node internals.
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 left 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/06da920ddb1b3ddf.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/util/IntervalTree.java:363
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) {
throw new IllegalStateException("node size is not one plus the sum of left and right!!!");View on GitHub (pinned to 1b7edd19c4)