stanfordnlp/CoreNLP · error · SsurgeonParseException

Unable to process node attribute keys for Ssurgeon operation

Error message

Unable to process node attribute keys for Ssurgeon operation

What it means

After the key checks, checkIllegalAttributes performs a dry run of fromCheapStrings(attributes) to validate that every attribute key/value can actually build a CoreLabel. If that helper signals an UnsupportedOperationException, the error is rewrapped as SsurgeonParseException with this message, so malformed or unknown node attribute keys fail early at pattern-construction time rather than at runtime.

Solutions

  1. Check the wrapped UnsupportedOperationException's cause message to find the offending key.
  2. Correct the attribute key spelling / use only keys supported by AnnotationLookup.toCoreKey.
  3. Validate the map by calling AddDep.checkIllegalAttributes (or fromCheapStrings) in a try-catch during script loading to fail fast with a clear message.

Example fix

// before (ssurgeon rule)
addedep -node AddDep -dep rel -attributes {lamma=dog}

// after
addedep -node AddDep -dep rel -attributes {lemma=dog}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java
for (String key : attributes.keySet()) {
  if (AnnotationLookup.toCoreKey(key) == null) {
    throw new IllegalArgumentException("Unknown attribute key: " + key);
  }
}

Try / catch

// Java
try {
  AddDep.checkIllegalAttributes(attrs);
} catch (SsurgeonParseException e) {
  Throwable cause = e.getCause(); // UnsupportedOperationException names the bad key/value
  log.severe("Bad node attribute: " + (cause != null ? cause.getMessage() : e.getMessage()));
}

Prevention

When it happens

Trigger: Passing an attributes map to AddDep where a key is not a recognized CoreAnnotation key (or a value cannot be converted, e.g. non-numeric value for a numeric annotation), so AddDep.fromCheapStrings throws UnsupportedOperationException which is wrapped by this error.

Common situations: Typos in attribute names in .ssurgeon files (e.g. "lamma" instead of "lemma"); using CoNLL-U column names that do not map to CoreAnnotations; supplying values of the wrong type for typed annotations.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/AddDep.java:169

   * Certain attributes cannot be edited, especially docid, sentid, idx,
   * or they mess up the hashmaps in the SemanticGraph
   */
  public static void checkIllegalAttributes(Map<String, String> attributes) {
    if (attributes.containsKey("idx")) {
      throw new SsurgeonParseException("Cannot manually set the index attribute.  If you need a moveWord operation, please file an issue on github.");
    }
    if (attributes.containsKey("sentIndex")) {
      throw new SsurgeonParseException("Cannot manually change the sentence index.  If you need an operation to change an entire sentence's sentIndex, please file an issue on github.");
    }
    if (attributes.containsKey("docID")) {
      throw new SsurgeonParseException("Cannot manually change a document ID.  If you need an operation to change an entire sentence's document ID, please file an issue on github.");
    }

    // if there's an exception, we'll barf when creating the pattern rather than at runtime
    try {
      CoreLabel newNodeObj = fromCheapStrings(attributes);
    } catch (UnsupportedOperationException e) {
      throw new SsurgeonParseException("Unable to process node attribute keys for Ssurgeon operation", e);
    }
  }

  /**
   * Given the keys and values of the CoreAnnotation attributes,
   * build a CoreLabel to use as the new word
   */
  public static CoreLabel fromCheapStrings(Map<String, String> attributes) {
    String[] keys = new String[attributes.size()];
    String[] values = new String[attributes.size()];
    int idx = 0;
    for (String key : attributes.keySet()) {
      String value = attributes.get(key);
      keys[idx] = key;
      values[idx] = value;
      ++idx;
    }
    final CoreLabel newWord = new CoreLabel(keys, values);

View on GitHub (pinned to 1b7edd19c4)