{"record":{"id":"1980234cb62b0454","repo":"stanfordnlp/CoreNLP","slug":"illegal-number-of-nodes-given-to-createsubtree-198023","errorCode":null,"errorMessage":"Illegal number of nodes given to createSubtree (","messagePattern":"Illegal number of nodes given to createSubtree \\(","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/tregex/tsurgeon/TsurgeonParser.jj","lineNumber":303,"sourceCode":"  operator = <INSERT> tree = TreeRoot(false) loc = Location()/*@bgen(jjtree)*/\n    {\n      jjtree.closeNodeScope(jjtn000, true);\n      jjtc000 = false;\n    }\n/*@egen*/\n    { return new InsertNode(tree, loc); }\n| operator = <CREATE_SUBTREE> tree = TreeRoot(false) nodeSelections = NodeSelectionList(new ArrayList<TsurgeonPattern>())/*@bgen(jjtree)*/\n    {\n      jjtree.closeNodeScope(jjtn000, true);\n      jjtc000 = false;\n    }\n/*@egen*/\n    { if (nodeSelections.size() == 1) {\n        return new CreateSubtreeNode(nodeSelections.get(0), tree);\n      } else if (nodeSelections.size() == 2) {\n        return new CreateSubtreeNode(nodeSelections.get(0), nodeSelections.get(1), tree);\n      } else {\n        throw new ParseException(\"Illegal number of nodes given to createSubtree (\" + nodeSelections.size() + \")\");\n      }\n    }\n| operator = <ADJOIN> tree = TreeRoot(true) child1 = NodeSelection()/*@bgen(jjtree)*/\n    {\n      jjtree.closeNodeScope(jjtn000, true);\n      jjtc000 = false;\n    }\n/*@egen*/\n    { return new AdjoinNode(tree, child1); }\n| operator = <ADJOIN_TO_HEAD> tree = TreeRoot(true) child1 = NodeSelection()/*@bgen(jjtree)*/\n    {\n      jjtree.closeNodeScope(jjtn000, true);\n      jjtc000 = false;\n    }\n/*@egen*/\n    { return new AdjoinToHeadNode(tree, child1); }\n| operator = <ADJOIN_TO_FOOT> tree = TreeRoot(true) child1 = NodeSelection()/*@bgen(jjtree)*/\n    {","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/tregex/tsurgeon/TsurgeonParser.jj#L285-L321","documentation":"ParseException thrown by the generated Tsurgeon parser when the createSubtree operator is given a number of node arguments other than 1 or 2. createSubtree takes a label (root) plus either one node to become the sole child or two nodes (head and dependent); any other arity is rejected. This copy lives in the generated TsurgeonParser.jj (line 303); the hand-written grammar is in TsurgeonParser.jjt:177.","triggerScenarios":"Executing a Tsurgeon script whose createSubtree operation's node-selection list has 0 or 3+ selections, e.g. \"createSubtree LABEL\" with no node selection or with a list of three nodes; the size check at TsurgeonParser.jj:303 throws.","commonSituations":"Hand-writing tsurgeon operation files with missing or extra node specifications; concatenating operations and leaving a dangling selection; misremembering whether createSubtree takes one or two arguments.","solutions":["Provide exactly one node selection (single child) or two (first = head, second = dependent) after the label.","Check the Tsurgeon script for a missing/extra node list after createSubtree LABEL.","Validate the operation arity programmatically before running Tsurgeon.processPatternsOnTree."],"exampleFix":"// before (three selections)\ncreateSubtree NP node1 node2 node3\n// after (head + dependent)\ncreateSubtree NP node1 node2","handlingStrategy":"validation","validationCode":"boolean validCreateSubtreeArity(String tsurgeonOp) {\n  String[] parts = tsurgeonOp.trim().split(\"\\\\s+\");\n  return parts.length >= 2 && parts[0].equals(\"createSubtree\") && (parts.length == 3 || parts.length == 4);\n}","typeGuard":null,"tryCatchPattern":"try { Tsurgeon.parseOperation(op); } catch (ParseException e) { throw new IllegalArgumentException(\"createSubtree needs exactly 1 or 2 node selections: \" + op, e); }","preventionTips":["Always give createSubtree a label plus one node (single child) or two nodes (head, dependent)","Parse all operations with Tsurgeon.parseOperation up front before applying to trees","Review concatenated tsurgeon scripts for dangling node lists"],"tags":["parser","tsurgeon","arity"],"backgroundTag":"missing-required-argument","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}