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

  1. Add at least one attribute to set, one attribute to remove, or morphological features to update/remove.
  2. Remove the editnode instruction from the rule entirely if no edit is intended.
  3. 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

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


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)