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
- Pass a String annotation key name (e.g. "words" or a registered classname) so EnvLookup can resolve it
- Pass a Class object directly, e.g. CoreAnnotations.TextAnnotation.class
- 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
- Always supply annotationField as a String key name or a Class
- Verify env lookup tables contain the annotation key classnames
- Avoid raw non-String values (numbers, lists) in rule attribute maps
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
- Unknown rule type:
- Error creating composite rule: no annotation field
- Cannot determine annotation key for
- Unknown LogPriorType:
- unsupported language
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)