stanfordnlp/CoreNLP · error · SsurgeonParseException
Cannot make an EditNode with no updated attributes, removed…
Error message
Cannot make an EditNode with no updated attributes, removed attributes, or updated/removed morphological features
What it means
An EditNode must actually change something. If the attributes map is empty, updateMorphoFeatures is null, and both removed lists are empty, the constructor throws SsurgeonParseException because the operation would be a no-op on the matched node.
Solutions
- Add at least one attribute to set, one attribute to remove, or morphological features to update/remove.
- Remove the editnode instruction from the rule entirely if no edit is intended.
- In rule-generation code, skip emitting editnode when all edit payloads are empty.
Example fix
// before
new EditNode("noun", Map.of(), null, List.of(), List.of()); // no-op
// after
new EditNode("noun", Map.of("lemma", "dog"), null, List.of(), List.of()); Defensive patterns
Strategy: validation
Validate before calling
// Java
boolean hasEdit = !attrs.isEmpty() || updateMorphoFeatures != null
|| !removedAttrs.isEmpty() || !removedMorpho.isEmpty();
if (!hasEdit) {
throw new IllegalArgumentException("EditNode would be a no-op; provide at least one edit");
} Try / catch
// Java
try {
EditNode op = new EditNode(node, attrs, morpho, removedAttrs, removedMorpho);
} catch (SsurgeonParseException e) {
log.warning("Dropping no-op editnode rule: " + e.getMessage());
} Prevention
- Skip emitting editnode instructions whose fields are all empty in generated rules.
- Audit .ssurgeon files for editnode lines left with no attribute arguments.
When it happens
Trigger: new EditNode("node", Map.of(), null, List.of(), List.of()) — an editnode rule whose -attributes, -updateMorphoFeatures, -removeAttributes, and -removeMorphoFeatures are all absent/empty.
Common situations: Generating editnode instructions from templates where all optional fields default to empty; editing .ssurgeon files and stripping all attribute arguments while leaving the instruction in place.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Cannot combine MWT out of only
- Cannot make a Lemmatize with no nodeName
- Cannot make an EditNode with no nodeName
- Cannot manually change a document ID. If you need an…
- Cannot manually change the sentence index. If you need an…
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/c0309e35da35f824.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/EditNode.java:37
* Edit an existing node to have new attributes.
*
* @author John Bauer
*/
public class EditNode extends SsurgeonEdit {
public static final String LABEL = "editNode";
final String nodeName;
final List<String> removedAttributes;
final List<String> removedMorpho;
final Map<String, String> attributes;
final Map<String, String> updateMorphoFeatures;
public EditNode(String nodeName, Map<String, String> attributes, String updateMorphoFeatures, List<String> removedAttributes, List<String> removedMorpho) {
if (nodeName == null) {
throw new SsurgeonParseException("Cannot make an EditNode with no nodeName");
}
if (attributes.size() == 0 && updateMorphoFeatures == null && removedAttributes.size() == 0 && removedMorpho.size() == 0) {
throw new SsurgeonParseException("Cannot make an EditNode with no updated attributes, removed attributes, or updated/removed morphological features");
}
AddDep.checkIllegalAttributes(attributes);
this.nodeName = nodeName;
this.attributes = new TreeMap<>(attributes);
if (updateMorphoFeatures != null) {
this.updateMorphoFeatures = new CoNLLUFeatures(updateMorphoFeatures);
} else {
this.updateMorphoFeatures = Collections.emptyMap();
}
this.removedAttributes = new ArrayList<>(removedAttributes);
for (String attr : removedAttributes) {
if (AnnotationLookup.toCoreKey(attr) == null) {
throw new SsurgeonParseException("Unknown attribute |" + attr + "| when building an EditNode operation");
}
}
this.removedMorpho = new ArrayList<>(removedMorpho);
}
View on GitHub (pinned to 1b7edd19c4)