{"record":{"id":"f75dfeb7c4e13c05","repo":"stanfordnlp/CoreNLP","slug":"setphrasehead-expected-a-headindex-0-indexed-for","errorCode":null,"errorMessage":"SetPhraseHead expected a -headIndex, 0-indexed for the node to use as the new head","messagePattern":"SetPhraseHead expected a -headIndex, 0-indexed for the node to use as the new head","errorType":"exception","errorClass":"SsurgeonParseException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java","lineNumber":32,"sourceCode":" * <br>\n * All of the words must currently be connected to themselves.  Eg, there would be one head which points to a different word, and the other words all point to that head.\n * <br>\n * If that condition is matched, then existing internal edges are replaced with edges to the new head, with the given reln <br>\n * If the head is changed, the edge out of the phrase (if it is not root) is changed to come from the new head <br>\n * Edges in to the phrase are also changed to point to the new head.\n * The purpose of that change is so for a noun phrase, for example, modifiers of that noun phrase such as nmod or nmod:desc now modify the new head\n */\npublic class SetPhraseHead extends SsurgeonEdit {\n  public static final String LABEL = \"setPhraseHead\";\n\n  final List<String> phrase;\n  final int headIndex;\n  final GrammaticalRelation relation;\n  final double weight;\n\n  public SetPhraseHead(List<String> nodes, Integer headIndex, GrammaticalRelation relation, double weight) {\n    if (headIndex == null) {\n      throw new SsurgeonParseException(\"SetPhraseHead expected a -headIndex, 0-indexed for the node to use as the new head\");\n    }\n    if (headIndex < 0 || headIndex >= nodes.size()) {\n      throw new SsurgeonParseException(\"-headIndex of \" + headIndex + \" is out of bounds for a phrase with \" + nodes.size() + \" words\");\n    }\n\n    if (relation == null) {\n      throw new SsurgeonParseException(\"SetPhraseHead expected a -reln to represent the dependency to use for the new phrase\");\n    }\n\n    this.phrase = new ArrayList<>(nodes);\n    this.headIndex = headIndex;\n    this.relation = relation;\n    this.weight = weight;\n  }\n\n  @Override\n  public String toEditString() {\n    StringWriter buf = new StringWriter();","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java#L14-L50","documentation":"SetPhraseHead collapses a list of matched nodes into one phrase and must know which member is the head via a 0-indexed headIndex. If the headIndex argument is null the constructor cannot build the phrase and throws SsurgeonParseException.","triggerScenarios":"new SetPhraseHead(nodes, null, relation, weight), or an Ssurgeon resource 'set-phrase-head' line lacking the -headIndex argument.","commonSituations":"Writing a rule and forgetting the -headIndex flag; a rule file line truncated at the argument; programmatic construction where headIndex was an unassigned Integer defaulting to null.","solutions":["Add the -headIndex argument (0-indexed position of the head node within the node list) to the set-phrase-head line","Pass a valid Integer index programmatically, e.g. 0 for the first node","Check the resource file syntax: set-phrase-head -node n1 -node n2 -headIndex 0 -reln ..."],"exampleFix":"// before\nnew SetPhraseHead(Arrays.asList(\"n1\",\"n2\"), null, reln, 1.0);\n// after\nnew SetPhraseHead(Arrays.asList(\"n1\",\"n2\"), 0, reln, 1.0);","handlingStrategy":"validation","validationCode":"if (headIndex == null) {\n  throw new IllegalArgumentException(\"set-phrase-head requires -headIndex (0-indexed)\");\n}\nif (headIndex < 0 || headIndex >= nodes.size()) {\n  throw new IllegalArgumentException(\"-headIndex \" + headIndex + \" out of bounds for \" + nodes.size() + \" nodes\");\n}","typeGuard":"boolean hasValidHeadIndex(Integer idx, int numNodes) { return idx != null && idx >= 0 && idx < numNodes; }","tryCatchPattern":"try {\n  op = new SetPhraseHead(nodes, headIndex, relation, weight);\n} catch (SsurgeonParseException e) {\n  log.error(\"Bad set-phrase-head rule: {}\", e.getMessage());\n  throw new RuleSyntaxException(e);\n}","preventionTips":["Always emit -headIndex when generating set-phrase-head rules","Pair every set of -node arguments with exactly one in-range -headIndex","Test-load each Ssurgeon rule file before running the batch"],"tags":["java","ssurgeon","missing-argument"],"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-16T04:17:20.429Z"}