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
- Verify the name in the SetRoots operation exactly matches a named node in the semgrex pattern (e.g. node=subject/{pos:NNP})
- Check the semgrex pattern actually matches and assigns every name referenced by SetRoots before evaluate runs
- Null-check the SemgrexMatcher result in custom pipelines, or wrap evaluate in try-catch for SsurgeonRuntimeException and log the rule name
- 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
- Keep the semgrex named nodes and ssurgeon operation arguments in one place/generated together
- Test the semgrex pattern matches and exposes every named node before wiring ssurgeon ops
- Re-check rule files after editing semgrex patterns
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
- Between when the incoming edge was found and now, the edge…
- Between when the internal phrase edge was found and now…
- Between when the outgoing edge was found and now, the edge…
- Cannot add new variable names under negation. Node '
- Cannot combine MWT out of only
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)