stanfordnlp/CoreNLP · error · IllegalArgumentException
Unsatisfiable annotator list
Error message
Unsatisfiable annotator list: ${annotators} What it means
ensurePrerequisiteAnnotators repeatedly removes annotators whose requirements are satisfied by others; if an entire iteration adds nothing, the requested annotator combination cannot be satisfied and it throws IllegalArgumentException 'Unsatisfiable annotator list'.
Solutions
- Include the full prerequisite chain explicitly, e.g. tokenize,ssplit,pos,lemma,ner.
- Let CoreNLP compute prerequisites (call ensurePrerequisiteAnnotators with the minimal intent list) instead of hand-editing.
- Check the printed list to find which annotator's requirements are unsatisfied.
- Upgrade CoreNLP - newer versions satisfy more combos automatically.
Example fix
// before
props.setProperty("annotators", "ner,coref"); // prerequisites missing
// after
props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner,coref"); Defensive patterns
Strategy: validation
Validate before calling
List<String> req = new ArrayList<>(Arrays.asList("tokenize","ssplit","pos","lemma"));
for (String a : requested) if (!req.contains(a)) req.add(a);
props.setProperty("annotators", String.join(",", req)); Try / catch
try { pipeline = new StanfordCoreNLP(props); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsatisfiable annotator list")) { log.error("Missing prerequisites in: {}", props.getProperty("annotators")); } throw e; } Prevention
- Always prepend tokenize,ssplit,pos,lemma when using ner/parse/coref.
- Do not hand-strip prerequisites when trimming pipelines for speed.
- Document the required chain per annotator in your config comments.
When it happens
Trigger: Passing an annotators list where some required prerequisite is missing and cannot be auto-added, e.g. requesting 'ner' or 'parse' dependent combos while excluding their prerequisites, or conflicting removals leaving unsatisfied requirements.
Common situations: Hand-trimming 'annotators' to speed up pipelines and accidentally removing prerequisites like tokenize/ssplit/pos; combining annotators whose requirements conflict in the given order.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unknown annotator
- Cannot infer requirements for annotator
- Unknown LogPriorType:
- unsupported language
- no sieve type specified
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/8a30ca3a8a413af0.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/pipeline/StanfordCoreNLP.java:546
// Weird hack to replace POS with POS tags from PARSE if we are already doing parse (and just parse)
if (useParseForPos && Annotator.STANFORD_POS.equals(prereq)) {
prereq = Annotator.STANFORD_PARSE;
}
if (!prereq.equals(candidate) && !orderedAnnotators.contains(prereq)) {
canAdd = false;
break;
}
}
// If so, add the annotator
if (canAdd) {
orderedAnnotators.add(candidate);
iter.remove();
somethingAdded = true;
}
}
// Make sure we're making progress every iteration, to prevent an infinite loop
if (!somethingAdded) {
throw new IllegalArgumentException("Unsatisfiable annotator list: " + StringUtils.join(annotators, ","));
}
}
// Remove depparse + parse -- these are redundant
if (orderedAnnotators.contains(STANFORD_PARSE) && !ArrayUtils.contains(annotators, STANFORD_DEPENDENCIES)) {
orderedAnnotators.remove(STANFORD_DEPENDENCIES);
}
// Tweak the properties, if necessary
// (set the mention annotator to use dependency trees, if appropriate)
if ((orderedAnnotators.contains(Annotator.STANFORD_COREF_MENTION) || orderedAnnotators.contains(Annotator.STANFORD_COREF))
&& !orderedAnnotators.contains(Annotator.STANFORD_PARSE) &&
!props.containsKey("coref.md.type")) {
props.setProperty("coref.md.type", "dep");
}
// (ensure regexner is after ner)
if (orderedAnnotators.contains(Annotator.STANFORD_NER) && orderedAnnotators.contains(STANFORD_REGEXNER)) {
orderedAnnotators.remove(STANFORD_REGEXNER);View on GitHub (pinned to 1b7edd19c4)