stanfordnlp/CoreNLP · error · RuntimeException
Error: looking for a non-existent parent in tree " + tree +…
Error message
Error: looking for a non-existent parent in tree " + tree + " for \"" + toString() + '"
What it means
Tsurgeon's location-parsing step in TreeLocation.evaluate computes the parent node under which an insertion/relocation index will be applied. When the relative node named by a $+ / $- (right/left sister) relation has no parent in the tree — i.e. it is the root, or it was detached by a prior operation — the library cannot compute an insertion point and throws this RuntimeException.
Solutions
- Check that the node referenced by $+/$- is not the root and has a parent in the tree
- Reorder tsurgeon operations so deletes/prunes that remove the anchor run after the $+/$- operation
- Use a relation that does not require a parent (e.g. anchor on a sibling node instead)
- Wrap processPatternsOnTree in try-catch for RuntimeException and skip trees that fail
Example fix
// before
Tsurgeon.processPatternsOnTree(new Pair<>(tregex, parseOperation("insert (NP foo) >0 $+root")), tree);
// after
// anchor on a non-root node instead: insert relative to a sister of the target
Tsurgeon.processPatternsOnTree(new Pair<>(tregex, parseOperation("insert (NP foo) >0 $-NP")), tree); Defensive patterns
Strategy: try-catch
Validate before calling
// before applying ops: ensure anchor node is not the root
private static boolean hasParentAnchors(TregexMatcher m, Tree root) {
return m.getMatch() != root;
} Type guard
if (relativeNode == null || relativeNode.parent(tree) == null) { skipOperation(); return; } Try / catch
try {
Tsurgeon.processPatternsOnTree(op, tree);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("non-existent parent")) { logSkip(tree); }
else throw e;
} Prevention
- Never anchor $+/$- relations on the root node
- Order operations so deletions happen after relational insertions
- Verify tregex named captures match non-root nodes
- Test tsurgeon scripts on single-node edge-case trees
When it happens
Trigger: A tsurgeon operation uses $+ or $- whose target node is the root of the matched tree, or a node deleted/pruned by an earlier operation in the same sequence, so relativeNode.parent(tree) returns null in evaluate.
Common situations: Writing an adjoin/insert operation that anchors on the root with $+/$-; running multi-operation tsurgeon scripts where an earlier delete/prune removes the ancestor the later operation references; applying patterns to single-node trees where the anchor has no sisters.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Error: Haven't dealt with relation " + relation + " yet.
- Tsurgeon.processPatternsOnTree failed to match label for…
- Error -- no foot node found for " + originalTreeString
- Error -- two foot nodes in subtree" + t.toString()
- No foot node found for " + auxTree
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/3d38fae59bf3d68c.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/tregex/tsurgeon/TreeLocation.java:62
this.coindexer = coindexer;
this.childMatcher = child.matcher(newNodeNames, coindexer);
}
Pair<Tree,Integer> evaluate(Tree tree, TregexMatcher tregex) {
int newIndex; // initialized below
Tree parent; // initialized below
Tree relativeNode = childMatcher.evaluate(tree, tregex);
Matcher m = daughterPattern.matcher(relation);
if (m.matches()) {
newIndex = Integer.parseInt(m.group(1))-1;
parent = relativeNode;
if(relation.charAt(1)=='-') // backwards.
newIndex = parent.children().length - newIndex;
} else {
parent = relativeNode.parent(tree);
if (parent == null) {
throw new RuntimeException("Error: looking for a non-existent parent in tree " + tree + " for \"" + toString() + '"');
}
int index = parent.objectIndexOf(relativeNode);
switch(relation) {
case "$+" :
newIndex = index;
break;
case "$-" :
newIndex = index+1;
break;
default :
throw new RuntimeException("Error: Haven't dealt with relation " + relation + " yet.");
}
}
return new Pair<>(parent, newIndex);
}
}
@OverrideView on GitHub (pinned to 1b7edd19c4)