stanfordnlp/CoreNLP · error · IllegalArgumentException

Invalid annotation key

Error message

Invalid annotation key 

What it means

When parsing rule attributes in SequenceMatchRules.TemplateExtractorFunc/AnnotationCreator update(), the 'annotationField' value must be a Class or a String resolvable via Env (lookupAnnotationKeyWithClassname). If it is neither (and no annotationField was already set), an IllegalArgumentException is thrown. This validates the CoreMap annotation key supplied in a tokensregex rule definition.

Solutions

  1. Pass a String annotation key name (e.g. "words" or a registered classname) so EnvLookup can resolve it
  2. Pass a Class object directly, e.g. CoreAnnotations.TextAnnotation.class
  3. Ensure env defaults/lookup tables are initialized with the annotation key classname before rule creation

Example fix

// before
attributes.put("annotationField", 42); // invalid key type
// after
attributes.put("annotationField", CoreAnnotations.TextAnnotation.class);
// or
attributes.put("annotationField", "text");
Defensive patterns

Strategy: validation

Validate before calling

Object annoKey = attributes.get("annotationField");
if (annoKey != null && !(annoKey instanceof Class) && !(annoKey instanceof String)) {
  throw new IllegalArgumentException("annotationField must be a Class or String key");
}

Type guard

boolean isValidAnnotationKey(Object o) {
  return o == null || o instanceof Class || o instanceof String;
}

Try / catch

try {
  SequenceMatchRules.createRule(env, attributes);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Invalid annotation key")) {
    attributes.put("annotationField", CoreAnnotations.TextAnnotation.class); // retry with Class
  }
}

Prevention

When it happens

Trigger: A rule file with `annotationField: <value>` where the value is not a Class and not a String key known to the Env (e.g. a Number, list, or an unresolvable non-String object); typically from programmatically built attribute maps with wrong types.

Common situations: Building rules programmatically and putting a wrong-typed object into the 'annotationField' attribute; custom rule languages that pass parsed non-string values.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/ling/tokensregex/SequenceMatchRules.java:258

          case "priority":
            priority = ((Number) Expressions.asObject(env, obj)).doubleValue();
            break;
          case "stage":
            stage = ((Number) Expressions.asObject(env, obj)).intValue();
            break;
          case "weight":
            weight = ((Number) Expressions.asObject(env, obj)).doubleValue();
            break;
          case "over":
            Object annoKey = Expressions.asObject(env, obj);
            if (annoKey instanceof Class) {
              annotationField = (Class) annoKey;
            } else if (annoKey instanceof String) {
              annotationField = EnvLookup.lookupAnnotationKeyWithClassname(env, (String) annoKey);
            } else if (annotationField == null) {
              annotationField = CoreMap.class;
            } else {
              throw new IllegalArgumentException("Invalid annotation key " + annoKey);
            }
            break;
          case "active":
            active = (Boolean) Expressions.asObject(env, obj);
            break;
          case "ruleType":
            ruleType = (String) Expressions.asObject(env, obj);
            break;
          case "matchFindType":
            matchFindType = SequenceMatcher.FindType.valueOf((String) Expressions.asObject(env, obj));
            break;
          case "matchWithResults":
            matchWithResults = ((Boolean) Expressions.asObject(env, obj)).booleanValue();
            break;
          case "matchedExpressionGroup":
            matchedExpressionGroup = ((Number) Expressions.asObject(env, obj)).intValue();
            break;
        }

View on GitHub (pinned to 1b7edd19c4)