{"record":{"id":"6894c0ddc381b77e","repo":"stanfordnlp/CoreNLP","slug":"tree-is-not-a-descendant-of-root","errorCode":null,"errorMessage":"Tree is not a descendant of root.","messagePattern":"Tree is not a descendant of root\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/Trees.java","lineNumber":50,"sourceCode":"    }\n    int maxHeight = 0;\n    for (Tree child : t.children()) {\n      maxHeight = Math.max(maxHeight, height(child));\n    }\n    return maxHeight + 1;\n  }\n  \n  /**\n   * Returns the positional index of the left edge of a tree <i>t</i>\n   * within a given root, as defined by the size of the yield of all\n   * material preceding <i>t</i>.\n   */\n  public static int leftEdge(Tree t, Tree root) {\n    MutableInteger i = new MutableInteger(0);\n    if (leftEdge(t, root, i)) {\n      return i.intValue();\n    } else {\n      throw new RuntimeException(\"Tree is not a descendant of root.\");\n//      return -1;\n    }\n  }\n\n  /**\n   * Returns the positional index of the left edge of a tree <i>t</i>\n   * within a given root, as defined by the size of the yield of all\n   * material preceding <i>t</i>.\n   * This method returns -1 if no path is found, rather than exceptioning.\n   *\n   * @see Trees#leftEdge(Tree, Tree)\n   */\n  public static int leftEdgeUnsafe(Tree t, Tree root) {\n    MutableInteger i = new MutableInteger(0);\n    if (leftEdge(t, root, i)) {\n      return i.intValue();\n    } else {\n      return -1;","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/Trees.java#L32-L68","documentation":"Trees.leftEdge(t, root) computes t's token position at the left edge by walking from root; the helper returns false when t is not reachable within root's subtree, so the public method throws RuntimeException.","triggerScenarios":"Calling Trees.leftEdge(t, root) where t belongs to a different tree than root, or t is not actually a descendant of root (e.g. a subtree copied out of the original tree, or two disjoint trees compared).","commonSituations":"Comparing nodes from parse trees of different sentences; using a stale subtree reference after re-parsing; mixing trees from gold and guess Treebanks in evaluation code.","solutions":["Ensure root is the actual containing tree of t (use the same Tree object hierarchy).","Pass the sentence's full Tree as root, not a sibling or unrelated subtree.","Catch RuntimeException and return -1 / handle the disjoint-tree case explicitly."],"exampleFix":"// before\nint edge = Trees.leftEdge(subtree, otherTreeRoot);\n// after\nif (Trees.isIn(subtree, root)) { int edge = Trees.leftEdge(subtree, root); }","handlingStrategy":"try-catch","validationCode":"// containment check\nboolean contains(Tree root, Tree t) { for (Tree sub : root) if (sub == t) return true; return false; }","typeGuard":null,"tryCatchPattern":"try { edge = Trees.leftEdge(t, root); } catch (RuntimeException e) { edge = -1; /* t not under root */ }","preventionTips":["Always pass the tree that actually contains the node as root.","Keep subtree references from the same parse as the root.","Re-acquire both t and root from the same Tree object after re-parsing."],"tags":["trees","argument-validation"],"backgroundTag":"invalid-argument-value","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"}