stanfordnlp/CoreNLP · error · SsurgeonParseException

SetPhraseHead expected a -headIndex, 0-indexed for the node…

Error message

SetPhraseHead expected a -headIndex, 0-indexed for the node to use as the new head

What it means

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.

Solutions

  1. Add the -headIndex argument (0-indexed position of the head node within the node list) to the set-phrase-head line
  2. Pass a valid Integer index programmatically, e.g. 0 for the first node
  3. Check the resource file syntax: set-phrase-head -node n1 -node n2 -headIndex 0 -reln ...

Example fix

// before
new SetPhraseHead(Arrays.asList("n1","n2"), null, reln, 1.0);
// after
new SetPhraseHead(Arrays.asList("n1","n2"), 0, reln, 1.0);
Defensive patterns

Strategy: validation

Validate before calling

if (headIndex == null) {
  throw new IllegalArgumentException("set-phrase-head requires -headIndex (0-indexed)");
}
if (headIndex < 0 || headIndex >= nodes.size()) {
  throw new IllegalArgumentException("-headIndex " + headIndex + " out of bounds for " + nodes.size() + " nodes");
}

Type guard

boolean hasValidHeadIndex(Integer idx, int numNodes) { return idx != null && idx >= 0 && idx < numNodes; }

Try / catch

try {
  op = new SetPhraseHead(nodes, headIndex, relation, weight);
} catch (SsurgeonParseException e) {
  log.error("Bad set-phrase-head rule: {}", e.getMessage());
  throw new RuleSyntaxException(e);
}

Prevention

When it happens

Trigger: new SetPhraseHead(nodes, null, relation, weight), or an Ssurgeon resource 'set-phrase-head' line lacking the -headIndex argument.

Common situations: 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.

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


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

Appendix: source

Thrown at src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SetPhraseHead.java:32

 * <br>
 * 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.
 * <br>
 * If that condition is matched, then existing internal edges are replaced with edges to the new head, with the given reln <br>
 * 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>
 * Edges in to the phrase are also changed to point to the new head.
 * 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
 */
public class SetPhraseHead extends SsurgeonEdit {
  public static final String LABEL = "setPhraseHead";

  final List<String> phrase;
  final int headIndex;
  final GrammaticalRelation relation;
  final double weight;

  public SetPhraseHead(List<String> nodes, Integer headIndex, GrammaticalRelation relation, double weight) {
    if (headIndex == null) {
      throw new SsurgeonParseException("SetPhraseHead expected a -headIndex, 0-indexed for the node to use as the new head");
    }
    if (headIndex < 0 || headIndex >= nodes.size()) {
      throw new SsurgeonParseException("-headIndex of " + headIndex + " is out of bounds for a phrase with " + nodes.size() + " words");
    }

    if (relation == null) {
      throw new SsurgeonParseException("SetPhraseHead expected a -reln to represent the dependency to use for the new phrase");
    }

    this.phrase = new ArrayList<>(nodes);
    this.headIndex = headIndex;
    this.relation = relation;
    this.weight = weight;
  }

  @Override
  public String toEditString() {
    StringWriter buf = new StringWriter();

View on GitHub (pinned to 1b7edd19c4)