stanfordnlp/CoreNLP · error · RuntimeException
Tsurgeon.processPatternsOnTree failed to match label for…
Error message
Tsurgeon.processPatternsOnTree failed to match label for pattern: " + op.first() + ", " + op.second()
What it means
In Tsurgeon.processPatternsOnTree, after a tregex match succeeds, the code re-runs matcher() on the updated tree; if that throws NullPointerException (typically because the tree or match structure is null after a previous operation rewrote it), it is wrapped in this RuntimeException naming the failing pattern and operation pair.
Solutions
- Make later patterns tolerant: re-anchor them so they only match structures that exist after earlier operations
- Split the processing into stages, calling processPatternsOnTree separately per operation set
- Validate the tree between operations (log/inspect it) to find which operation produces the null match
- Catch RuntimeException and skip/restore the tree for the failing sentence
Example fix
// before List<Pair<TregexPattern,TsurgeonPattern>> ops = ...; // ops assume deleted nodes still exist Tsurgeon.processPatternsOnTree(ops, tree); // after // run destructive ops first, then dependent ops on the updated tree Tsurgeon.processPatternsOnTree(Collections.singletonList(destructiveOp), tree); Tsurgeon.processPatternsOnTree(Collections.singletonList(dependentOp), tree);
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the tree matches before applying dependent operations
if (tregex.matcher(tree).find()) {
Tsurgeon.processPatternsOnTree(Collections.singletonList(op), tree);
} Type guard
if (tree == null || tree.label() == null) { skip(); return; } Try / catch
try {
tree = Tsurgeon.processPatternsOnTree(ops, tree);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("failed to match label")) {
log.warn("Skipping sentence: pattern no longer matches after earlier op", e);
} else throw e;
} Prevention
- Design each tregex pattern to match structures surviving earlier operations
- Split dependent operations into separate processPatternsOnTree stages
- Log the tree after each operation when debugging chains
- Avoid operations that delete nodes referenced by later patterns
When it happens
Trigger: Running a sequence of (tregex, tsurgeon) pairs where an earlier operation deletes or restructures nodes so that a later pattern's matcher on the modified tree produces a null label/match, hitting the NPE catch in processPatternsOnTree.
Common situations: Chained tsurgeon scripts where op N's output violates op N+1's tregex assumptions; delete/prune followed by operations that assume the node still exists; coindexation nodes removed by earlier edits.
Related errors
- Error: looking for a non-existent parent in tree " + tree +…
- Error: Haven't dealt with relation " + relation + " yet.
- Null node fetched by Tsurgeon operation for node:
- Error initializing coref system
- Error making document
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/dcdedccc5538fe6e.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/tregex/tsurgeon/Tsurgeon.java:627
}
TregexMatcher m = op.first().matcher(t);
TsurgeonMatcher tsm = op.second().matcher();
while (m.find()) {
matchedOnTree = true;
t = tsm.evaluate(t,m);
if (t == null) {
if (DEBUG) {
log.info(" Matched, but t == null!");
}
return null;
}
if (DEBUG) {
log.info(" Matched! Update: " + t);
}
m = op.first().matcher(t);
}
} catch (NullPointerException npe) {
throw new RuntimeException("Tsurgeon.processPatternsOnTree failed to match label for pattern: " + op.first() + ", " + op.second(), npe);
}
}
return t;
}
/**
* Parses an operation string into a {@link TsurgeonPattern}. Throws an {@link TsurgeonParseException} if
* the operation string is ill-formed.
* <p>
* Example of use:
* <p>
* <code>
* TsurgeonPattern p = Tsurgeon.parseOperation("prune ed");
* </code>
* @param operationString The operation to perform, as a text string
* @return the operation pattern.View on GitHub (pinned to 1b7edd19c4)