stanfordnlp/CoreNLP · error · RuntimeException
Transformer did not change TreeGraphNode into another…
Error message
Transformer did not change TreeGraphNode into another TreeGraphNode: <transformer>
What it means
The GrammaticalStructure constructor optionally applies a TreeTransformer to the TreeGraphNode it built. Since a grammatical structure's root must remain a TreeGraphNode, if the transformer returns a plain Tree (or another Tree subtype), the invariant is broken and this RuntimeException is thrown, naming the offending transformer.
Solutions
- Modify the transformer so it returns TreeGraphNode objects (e.g. by copying graph structure or building nodes via a TreeGraphNodeFactory)
- Remove the transformer argument (pass null) if no transformation is actually required
- Wrap the transformer's output: convert the resulting plain Tree back into a TreeGraphNode before returning
- Use a transformer implementation known to be compatible with grammatical-structure construction
Example fix
// before
public Tree transformTree(Tree t) { return t.deepCopy(); } // plain Tree
// after
public Tree transformTree(Tree t) { return new TreeGraphNode(t, tf); } // tf: TreeGraphNodeFactory Defensive patterns
Strategy: type-guard
Validate before calling
Tree out = transformer.transformTree(treeGraph);
if (!(out instanceof TreeGraphNode)) throw new IllegalArgumentException("Transformer must return TreeGraphNode"); Type guard
boolean isSafeTransformer(TreeTransformer t, TreeGraphNode input) {
return t.transformTree(input) instanceof TreeGraphNode;
} Try / catch
try {
GrammaticalStructure gs = new EnglishGrammaticalStructure(tree, puncFilter, hf, transformer);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Transformer did not change")) {
// retry without transformer (null) or fix transformer
} else throw e;
} Prevention
- Unit-test custom transformers against TreeGraphNode inputs
- Base transformers on TreeGraphNode trees so graph structure is preserved
- Pass null when no transformation is needed
- Document transformer contracts (must return TreeGraphNode)
When it happens
Trigger: Passing a transformer (e.g. some SemanticHeadFinder-based or custom TreeTransformer) to the GrammaticalStructure constructor whose transformTree() returns a Tree that is not a TreeGraphNode; wrapping a structure-building pipeline with a transformer written for plain Trees.
Common situations: Custom transformers (e.g. coordinate-structure flattening, node-pruning) that build new Tree nodes instead of TreeGraphNode; reusing transformers meant for the parser pipeline inside dependency-construction code.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- addFeature was called with a features object that is…
- Unexpected node class
- Unknown value for span
- Attempting to remove features based on weight from a…
- String match result must be referred to by group id
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/b28df46a1a27043b.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/GrammaticalStructure.java:171
* punctuation word strings, and true otherwise.
* If punctuation dependencies should be kept, you
* should pass in a {@code Filters.<String>acceptFilter()}.
* @param tagFilter Appears to be unused (filters out tags??)
*/
public GrammaticalStructure(Tree t, Collection<GrammaticalRelation> relations,
Lock relationsLock, TreeTransformer transformer,
HeadFinder hf, Predicate<String> puncFilter,
Predicate<String> tagFilter) {
TreeGraphNode treeGraph = new TreeGraphNode(t, (TreeGraphNode) null);
// TODO: create the tree and reuse the leaf labels in one pass,
// avoiding a wasteful copy of the labels.
Trees.setLeafLabels(treeGraph, t.yield());
Trees.setLeafTagsIfUnset(treeGraph);
//System.out.println(treeGraph.toPrettyString(2));
if (transformer != null) {
Tree transformed = transformer.transformTree(treeGraph);
if (!(transformed instanceof TreeGraphNode)) {
throw new RuntimeException("Transformer did not change TreeGraphNode into another TreeGraphNode: " + transformer);
}
this.root = (TreeGraphNode) transformed;
} else {
this.root = treeGraph;
}
//System.out.println(this.root.toPrettyString(2));
indexNodes(this.root);
// add head word and tag to phrase nodes
if (hf == null) {
throw new AssertionError("Cannot use null HeadFinder");
}
try {
root.percolateHeads(hf);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Cannot process tree:\n" + t, e);
}
if (root.value() == null) {
root.setValue("ROOT"); // todo: cdm: it doesn't seem like this line should be hereView on GitHub (pinned to 1b7edd19c4)