stanfordnlp/CoreNLP · error · ParseException

Illegal number of nodes given to createSubtree (" +…

Error message

Illegal number of nodes given to createSubtree (" + nodeSelections.size() + ")

What it means

The generated TsurgeonParser's Operation rule for the createSubtree operator only accepts exactly one or two node selections. Any other count throws ParseException("Illegal number of nodes given to createSubtree (...)"). createSubtree defines a new subtree whose structure is determined by the one or two named nodes.

Solutions

  1. Reduce or supply arguments so createSubtree has exactly one or two named-node arguments
  2. Check the tregex pattern defines the node names used by createSubtree (all arguments must be named captures)
  3. Validate the operation string with Tsurgeon.parseOperation before running on trees
  4. Catch ParseException/TsurgeonParseException when loading user-supplied scripts and report the argument count

Example fix

// before
createSubtree n1 n2 n3
// after
createSubtree n1 n2
Defensive patterns

Strategy: validation

Validate before calling

String[] args = opString.trim().split("\\s+");
if (args[0].equals("createSubtree") && (args.length < 2 || args.length > 3)) {
  throw new IllegalArgumentException("createSubtree takes exactly 1 or 2 node arguments: " + opString);
}

Try / catch

try { Tsurgeon.parseOperation(opString); } catch (ParseException | TsurgeonParseException e) { reportBadScriptLine(opString, e); }

Prevention

When it happens

Trigger: Writing a createSubtree operation in a tsurgeon script with zero, or three or more node arguments, e.g. "createSubtree n1 n2 n3" or "createSubtree" with no named nodes matched by the tregex.

Common situations: Misunderstanding createSubtree's signature (it takes 1 or 2 nodes: child/label and optional parent); typos duplicating node names; scripts auto-generated from templates with variable argument counts.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/0726e967018da080. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/trees/tregex/tsurgeon/TsurgeonParser.java:268

              tree = TreeRoot(false);
              loc = Location();
jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
{if ("" != null) return new InsertNode(tree, loc);}
            } else {
              switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
              case CREATE_SUBTREE:{
                operator = jj_consume_token(CREATE_SUBTREE);
                tree = TreeRoot(false);
                nodeSelections = NodeSelectionList(new ArrayList<TsurgeonPattern>());
jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
if (nodeSelections.size() == 1) {
        {if ("" != null) return new CreateSubtreeNode(nodeSelections.get(0), tree);}
      } else if (nodeSelections.size() == 2) {
        {if ("" != null) return new CreateSubtreeNode(nodeSelections.get(0), nodeSelections.get(1), tree);}
      } else {
        {if (true) throw new ParseException("Illegal number of nodes given to createSubtree (" + nodeSelections.size() + ")");}
      }
                break;
                }
              case ADJOIN:{
                operator = jj_consume_token(ADJOIN);
                tree = TreeRoot(true);
                child1 = NodeSelection();
jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
{if ("" != null) return new AdjoinNode(tree, child1);}
                break;
                }
              case ADJOIN_TO_HEAD:{
                operator = jj_consume_token(ADJOIN_TO_HEAD);
                tree = TreeRoot(true);
                child1 = NodeSelection();
jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;

View on GitHub (pinned to 1b7edd19c4)