stanfordnlp/CoreNLP · error · IllegalArgumentException
Cannot infer requirements for annotator
Error message
Cannot infer requirements for annotator: ${annotator} What it means
After confirming an annotator exists, ensurePrerequisiteAnnotators looks it up in Annotator.DEFAULT_REQUIREMENTS to compute its prerequisite chain. If the annotator has no entry there, its requirements cannot be inferred and an IllegalArgumentException is thrown.
Solutions
- Replace the custom annotator with a built-in one that has requirement metadata.
- Implement the Annotator.Requirements interface / provide a Requirements implementation so requirements can be inferred.
- Upgrade/downgrade CoreNLP so the annotator has a DEFAULT_REQUIREMENTS entry.
- Order the annotators manually in the 'annotators' property and avoid the path that infers requirements, if API allows.
Example fix
// before
props.setProperty("annotators", "tokenize,ssplit,mycustom"); // mycustom has no requirements
// after
props.setProperty("customAnnotatorClass.mycustom", "com.example.MyAnnotator");
props.setProperty("annotators", "tokenize,ssplit"); // handle custom annotator separately Defensive patterns
Strategy: validation
Validate before calling
for (String a : annotators) {
if (!Annotator.DEFAULT_REQUIREMENTS.containsKey(a.toLowerCase()) &&
!isBuiltinAnnotator(a)) {
throw new IllegalArgumentException("Annotator lacks requirement metadata: " + a);
}
} Try / catch
try { StanfordCoreNLP.ensurePrerequisiteAnnotators(props, annotators, true); } catch (IllegalArgumentException e) { /* fall back to manually ordered annotator list */ } Prevention
- Give custom Annotator implementations a Requirements implementation.
- Keep custom annotators out of the auto-prerequisite path unless metadata exists.
- Pin a CoreNLP version where all requested annotators have DEFAULT_REQUIREMENTS entries.
When it happens
Trigger: Requesting a registered annotator (often a custom one registered via customAnnotatorClass, or one lacking a DEFAULT_REQUIREMENTS entry) in ensurePrerequisiteAnnotators, e.g. via ensurePrerequisiteAnnotators call on a pipeline requiring dependency ordering.
Common situations: Custom annotators plugged in through customAnnotatorClass that were never added to DEFAULT_REQUIREMENTS; CoreNLP version skew where an annotator exists but requirements metadata was added later.
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 annotator
- Unsatisfiable annotator list
- Unknown LogPriorType:
- unsupported language
- no sieve type specified
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/a073882356cb1413.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/pipeline/StanfordCoreNLP.java:498
*/
public static String ensurePrerequisiteAnnotators(String[] annotators, Properties props) {
int posIndex = ArrayUtils.indexOf(annotators, Annotator.STANFORD_POS);
int parseIndex = ArrayUtils.indexOf(annotators, Annotator.STANFORD_PARSE);
boolean useParseForPos = ((parseIndex >= 0) && (posIndex < 0)); // Already doing the parsing, use the parsing for the pos tag
// Get an unordered set of annotators
Set<String> unorderedAnnotators = new LinkedHashSet<>(); // linked to preserve order
Collections.addAll(unorderedAnnotators, annotators);
for (String annotator : annotators) {
// Add the annotator
if (!getNamedAnnotators().containsKey(annotator.toLowerCase())) {
throw new IllegalArgumentException("Unknown annotator: " + annotator);
}
// Add its transitive dependencies
unorderedAnnotators.add(annotator.toLowerCase());
if (!Annotator.DEFAULT_REQUIREMENTS.containsKey(annotator.toLowerCase())) {
throw new IllegalArgumentException("Cannot infer requirements for annotator: " + annotator);
}
Queue<String> fringe = new LinkedList<>(Annotator.DEFAULT_REQUIREMENTS.get(annotator.toLowerCase()));
int ticks = 0;
while (!fringe.isEmpty()) {
ticks += 1;
if (ticks == 1000000) {
throw new IllegalStateException("[INTERNAL ERROR] Annotators have a circular dependency.");
}
String prereq = fringe.poll();
unorderedAnnotators.add(prereq);
fringe.addAll(Annotator.DEFAULT_REQUIREMENTS.get(prereq.toLowerCase()));
}
}
if (useParseForPos) {
unorderedAnnotators.remove(Annotator.STANFORD_POS);
}
View on GitHub (pinned to 1b7edd19c4)