stanfordnlp/CoreNLP · error · SsurgeonRuntimeException

Ssurgeon rule tried to set root to

Error message

Ssurgeon rule tried to set root to ${name} but that name does not exist in the semgrex results

What it means

SetRoots.evaluate() resolves each name in newRootNames to a node via getNamedNode(name, sm), which returns the IndexedWord matched by a named semgrex node. If a name has no match, the rule cannot set roots and throws SsurgeonRuntimeException naming the missing node.

Solutions

  1. Verify the name in the SetRoots operation exactly matches a named node in the semgrex pattern (e.g. node=subject/{pos:NNP})
  2. Check the semgrex pattern actually matches and assigns every name referenced by SetRoots before evaluate runs
  3. Null-check the SemgrexMatcher result in custom pipelines, or wrap evaluate in try-catch for SsurgeonRuntimeException and log the rule name
  4. Regenerate the ssurgeon rule from the current semgrex pattern if the pattern was recently edited

Example fix

// before: pattern names nothing, rule references 'newroot'
Ssurgeon.setRoots("newroot"); pattern = "{word:dog}";
// after: name the node in the pattern
pattern = "{word:dog}=newroot"; Ssurgeon.setRoots("newroot");
Defensive patterns

Strategy: validation

Validate before calling

// verify all names referenced by SetRoots are present in the pattern string
for (String name : newRootNames) {
  if (!patternString.contains("=" + name)) throw new IllegalArgumentException("pattern does not name node: " + name);
}

Try / catch

try { op.evaluate(sg, sm); } catch (SsurgeonRuntimeException e) { if (e.getMessage().contains("does not exist in the semgrex results")) { log.error("Fix semgrex pattern to name node: " + e.getMessage()); } else { throw e; } }

Prevention

When it happens

Trigger: An ssurgeon SetRoots operation referencing a -node name (e.g. -root newroot) that the accompanying semgrex pattern never assigns, either because the name is misspelled or because the semgrex match did not capture that node.

Common situations: Typo between the semgrex pattern's named node and the SetRoots -root argument; editing a pattern so the named node no longer exists; reusing a hand-written ssurgeon rule file against a changed semgrex expression.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

 */
public class SetRoots extends SsurgeonEdit {
  public static final String LABEL = "setRoots";
  List<String> newRootNames;
  public SetRoots(List<String> newRootNames) {
    this.newRootNames = newRootNames;
  }

  /**
   * If executed twice on the same graph, the second time there
   * will be no further updates
   */
  @Override
  public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
    Set<IndexedWord> newRoots = new LinkedHashSet<>();
    for (String name : newRootNames) {
      IndexedWord root = getNamedNode(name, sm);
      if (root == null) {
        throw new SsurgeonRuntimeException("Ssurgeon rule tried to set root to " + name + " but that name does not exist in the semgrex results");
      }
      newRoots.add(root);
    }
    if (newRoots.equals(sg.getRoots()))
      return false;
    sg.setRoots(newRoots);
    return true;
  }

  @Override
  public String toEditString() {
    StringWriter buf = new StringWriter();
    buf.write(LABEL);
    for (String name : newRootNames) {
      buf.write("\t");
      buf.write(name);
    }
    return buf.toString();

View on GitHub (pinned to 1b7edd19c4)