stanfordnlp/CoreNLP · error · ParseException
Illegal number of nodes given to createSubtree (
Error message
Illegal number of nodes given to createSubtree (
What it means
Same error as the generated parser at TsurgeonParser.jj:303, but this is the source grammar location (TsurgeonParser.jjt:177): createSubtree only supports one or two node selections. The parser builds a CreateSubtreeNode from the collected selections and throws a ParseException for any other count.
Solutions
- Restrict createSubtree usage to 1 or 2 node selections in the tsurgeon script.
- If you need to group more than two nodes, chain multiple createSubtree/adjoin operations.
- Update downstream generators to assert list size ∈ {1,2} before emitting the operation.
Example fix
// before createSubtree VP n1 n2 n3 // after createSubtree VP n1 n2
Defensive patterns
Strategy: validation
Validate before calling
boolean opArityOk(String op) {
String[] p = op.trim().split("\\s+");
return !p[0].equals("createSubtree") || (p.length == 3 || p.length == 4);
} Try / catch
try { return Tsurgeon.parseOperation(script); } catch (ParseException e) { log.error("Bad createSubtree arity: " + script); return null; } Prevention
- Keep createSubtree to <= 2 selections; chain operations for larger groupings
- Validate generated tsurgeon operations in tests
- Pin the CoreNLP version so grammar behavior is stable
When it happens
Trigger: A Tsurgeon operation "createSubtree <label> <nodes>" where the NodeSelectionList resolves to 0, 3, or more selections when the operation block executes.
Common situations: Editing .jjt grammar or tsurgeon scripts and changing the selection count; writing operations generically from a template that emits a variable-length node list.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Illegal number of nodes given to createSubtree (
- : Parser grammar does not exist
- : No 1best segmentation available
- : Does not support parse operation.
- Field already defined:
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/3d709a44f83deee8.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/tregex/tsurgeon/TsurgeonParser.jjt:177
operator = <REPLACE> child1 = NodeSelection() treeList = TreeList(false)
{ return new ReplaceNode(child1,treeList); }
| operator = <MOVE> child1 = NodeSelection() loc = Location()
{ return new MoveNode(child1, loc, false); }
| operator = <MOVE_PRUNE> child1 = NodeSelection() loc = Location()
{ return new MoveNode(child1, loc, true); }
| LOOKAHEAD(3)
operator = <INSERT> child1 = NodeSelection() loc = Location()
{ return new InsertNode(child1, loc); }
| LOOKAHEAD(3)
operator = <INSERT> tree = TreeRoot(false) loc = Location()
{ return new InsertNode(tree, loc); }
| operator = <CREATE_SUBTREE> tree = TreeRoot(false) nodeSelections = NodeSelectionList(new ArrayList<TsurgeonPattern>())
{ if (nodeSelections.size() == 1) {
return new CreateSubtreeNode(nodeSelections.get(0), tree);
} else if (nodeSelections.size() == 2) {
return new CreateSubtreeNode(nodeSelections.get(0), nodeSelections.get(1), tree);
} else {
throw new ParseException("Illegal number of nodes given to createSubtree (" + nodeSelections.size() + ")");
}
}
| operator = <ADJOIN> tree = TreeRoot(true) child1 = NodeSelection()
{ return new AdjoinNode(tree, child1); }
| operator = <ADJOIN_TO_HEAD> tree = TreeRoot(true) child1 = NodeSelection()
{ return new AdjoinToHeadNode(tree, child1); }
| operator = <ADJOIN_TO_FOOT> tree = TreeRoot(true) child1 = NodeSelection()
{ return new AdjoinToFootNode(tree, child1); }
| operator = <COINDEX> nodeSelections = NodeSelectionList(new ArrayList<TsurgeonPattern>())
{ return new CoindexNodes(nodeSelections.toArray(new TsurgeonPattern[] {})); }
}
TreeLocation Location() :
{
Token rel;
TsurgeonPattern child;
}
{View on GitHub (pinned to 1b7edd19c4)