{"record":{"id":"9e27cafc36fbd142","repo":"stanfordnlp/CoreNLP","slug":"node-is-not-on-the-correct-side","errorCode":null,"errorMessage":"node is not on the correct side!!!","messagePattern":"node is not on the correct side!!!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/IntervalTree.java","lineNumber":402,"sourceCode":"        if (node.left.parent != node) {\n          throw new IllegalStateException(\"node left parent is not same as node!!!\");\n        }\n      }\n      if (node.right != null) {\n        if (node.right.parent != node) {\n          throw new IllegalStateException(\"node right parent is not same as node!!!\");\n        }\n      }\n      if (node.parent != null) {\n        // Go up parent and make sure we are on correct side\n        TreeNode<E,T> n = node;\n        while (n != null && n.parent != null) {\n          // Check we are either right or left\n          if (n == n.parent.left) {\n            // Check that node is less than the parent\n            if (node.value != null) {\n              if (node.value.getInterval().compareTo(n.parent.value.getInterval()) > 0) {\n                throw new IllegalStateException(\"node is not on the correct side!!!\");\n              }\n            }\n          } else if (n == n.parent.right) {\n            // Check that node is greater than the parent\n            if (node.value.getInterval().compareTo(n.parent.value.getInterval()) <= 0) {\n              throw new IllegalStateException(\"node is not on the correct side!!!\");\n            }\n          } else {\n            throw new IllegalStateException(\"node is not parent's left or right child!!!\");\n          }\n          n = n.parent;\n        }\n      }\n      if (node.left != null) todo.add(node.left);\n      if (node.right != null) todo.add(node.right);\n    }\n  }\n","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/IntervalTree.java#L384-L420","documentation":"check() validates the BST ordering invariant by walking a node up to the root: if the node sits in its parent's LEFT subtree, its interval must compare <= every ancestor's interval on that path. This IllegalStateException fires when a left-side node's interval compares greater than its parent's, i.e. the search-order property is violated and overlap/ranking queries would return wrong answers.","triggerScenarios":"check() (or balance()/rotateUp()) climbs from a node and finds node.value.getInterval().compareTo(parent.value.getInterval()) > 0 for a node in its parent's left subtree — after a rotation or insert placed a node on the wrong side.","commonSituations":"Hit when the interval comparator is inconsistent with insertion order (e.g. custom Interval types with non-transitive compareTo); after concurrent mutation; after rotation bugs during rebalancing in CoreNLP.","solutions":["Verify your interval type's compareTo/getInterval ordering is a proper total order consistent across all intervals.","Rebuild the tree (new IntervalTree, re-insert intervals) to restore correct ordering.","Do not mutate interval endpoints after insertion; remove and re-insert instead.","Single-thread or lock access; report a minimal reproducible insert/remove sequence to CoreNLP if public API alone fails."],"exampleFix":"// before: inconsistent comparator breaks ordering invariants\npublic int compareTo(Interval other) { return (int)(this.length() - other.length()); }\n// after: compare by start then end, a valid total order\npublic int compareTo(Interval other) {\n  int c = this.getStart().compareTo(other.getStart());\n  return c != 0 ? c : this.getEnd().compareTo(other.getEnd());\n}","handlingStrategy":"validation","validationCode":"// Validate comparator consistency before inserting\nboolean orderingConsistent(List<Interval<E>> ivs) {\n  for (int i = 0; i < ivs.size(); i++)\n    for (int j = i + 1; j < ivs.size(); j++) {\n      int a = ivs.get(i).compareTo(ivs.get(j));\n      int b = ivs.get(j).compareTo(ivs.get(i));\n      if (Integer.signum(a) != -Integer.signum(b)) return false; // antisymmetry broken\n    }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  tree.insert(iv, v);\n  tree.check(tree.root);\n} catch (IllegalStateException e) {\n  tree = rebuildTree(intervals);\n}","preventionTips":["Implement compareTo for intervals as a valid total order (start then end); never compare derived values like length.","Do not mutate interval endpoints after insertion.","Test the comparator with a sorting routine before feeding intervals to the tree.","Keep check() enabled in tests to catch ordering drift immediately."],"tags":["interval-tree","invariant","bst-ordering","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"}