stanfordnlp/CoreNLP · error · IllegalStateException

max end is not as expected!!!

Error message

max end is not as expected!!!

What it means

Each TreeNode caches maxEnd = the maximum interval endpoint in its subtree so overlap queries work. check() recomputes maxEnd from the node's own value and its children's cached values and throws this IllegalStateException when the stored maxEnd differs. It means an augment value was not recomputed after insert/remove/rotation — i.e. the tree's internal bookkeeping is stale or corrupted.

Solutions

  1. Never mutate an Interval (or its endpoints) after inserting it into the tree; remove and re-insert with the new value instead.
  2. Ensure the interval type's getInterval()/compareTo implement a consistent endpoint ordering so maxEnd recomputation matches caching.
  3. Rebuild the tree to restore consistent maxEnd values if corruption already occurred.
  4. Reproduce minimal failing insert/remove sequence and report to Stanford CoreNLP if triggered purely by public API.

Example fix

// before
interval.setEnd(newEnd); // mutates a stored interval, maxEnd now stale
// after
tree.remove(interval, value);
Interval<E> updated = new Interval<>(interval.getStart(), newEnd);
tree.insert(updated, value);
Defensive patterns

Strategy: validation

Validate before calling

// Guard: never insert an interval you plan to mutate later
boolean safeToInsert(Interval<E> iv) {
  return iv != null && iv.getInterval() != null && isEffectivelyImmutable(iv);
}

Try / catch

try {
  tree.check(tree.root);
} catch (IllegalStateException e) {
  if (e.getMessage().contains("max end")) { tree = rebuildTree(intervals); }
}

Prevention

When it happens

Trigger: check() (or balance()/rotateUp() that invoke it) finds recomputed maxEnd (max of node value's endpoint, leftMax, rightMax) not equal to node.maxEnd — after an operation that changed the subtree without updating maxEnd.

Common situations: Seen when debugging custom interval types whose compareTo/endpoint semantics are inconsistent; when mutation of an Interval object after insertion changes its endpoint without updating the tree; after rotation bugs in CoreNLP's IntervalTree.

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


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/c1f4c3cf7a75357e. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/util/IntervalTree.java:378

      }
      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!!!");
      }
      if (node.left != null) {
        if (node.left.parent != node) {
          throw new IllegalStateException("node left parent is not same as node!!!");
        }
      }
      if (node.right != null) {
        if (node.right.parent != node) {
          throw new IllegalStateException("node right parent is not same as node!!!");
        }
      }
      if (node.parent != null) {
        // Go up parent and make sure we are on correct side
        TreeNode<E,T> n = node;
        while (n != null && n.parent != null) {

View on GitHub (pinned to 1b7edd19c4)