{"record":{"id":"06da920ddb1b3ddf","repo":"stanfordnlp/CoreNLP","slug":"empty-node-shouldn-t-have-right-branch","errorCode":null,"errorMessage":"Empty node shouldn't have right branch","messagePattern":"Empty node shouldn't have right branch","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/IntervalTree.java","lineNumber":363,"sourceCode":"  private void adjust(TreeNode<E,T> node) {\n    adjustUpwards(node, node.parent);\n  }\n\n  public void check() {\n    check(root);\n  }\n\n  public void check(TreeNode<E,T> treeNode) {\n    Stack<TreeNode<E,T>> todo = new Stack<>();\n    todo.add(treeNode);\n    while (!todo.isEmpty()) {\n      TreeNode<E,T> node = todo.pop();\n      if (node == node.parent) {\n        throw new IllegalStateException(\"node is same as parent!!!\");\n      }\n      if (node.isEmpty()) {\n        if (node.left != null) throw new IllegalStateException(\"Empty node shouldn't have left branch\");\n        if (node.right != null) throw new IllegalStateException(\"Empty node shouldn't have right branch\");\n        continue;\n      }\n      int leftSize = (node.left != null)? node.left.size:0;\n      int rightSize = (node.right != null)? node.right.size:0;\n      E leftMax = (node.left != null)? node.left.maxEnd:null;\n      E rightMax = (node.right != null)? node.right.maxEnd:null;\n      E maxEnd = node.value.getInterval().getEnd();\n      if (leftMax != null && leftMax.compareTo(maxEnd) > 0) {\n        maxEnd = leftMax;\n      }\n      if (rightMax != null && rightMax.compareTo(maxEnd) > 0) {\n        maxEnd = rightMax;\n      }\n      if (!maxEnd.equals(node.maxEnd)) {\n        throw new IllegalStateException(\"max end is not as expected!!!\");\n      }\n      if (node.size != leftSize + rightSize + 1) {\n        throw new IllegalStateException(\"node size is not one plus the sum of left and right!!!\");","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/IntervalTree.java#L345-L381","documentation":"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.","triggerScenarios":"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.","commonSituations":"Encountered while debugging interval deletion in CoreNLP; after concurrent unsynchronized insert/remove on a shared tree; after external code or deserialization replaced node internals.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Detect corruption right after removals\ntry {\n  tree.check(tree.root);\n  valid = true;\n} catch (IllegalStateException e) {\n  valid = false; // empty node still carries a branch -> rebuild\n}","typeGuard":null,"tryCatchPattern":"try {\n  tree.check(tree.root);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Empty node\")) { tree = rebuildTree(intervals); }\n}","preventionTips":["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."],"tags":["interval-tree","invariant","empty-node","corenlp"],"backgroundTag":"internal-invariant-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"}