{"record":{"id":"8a30ca3a8a413af0","repo":"stanfordnlp/CoreNLP","slug":"unsatisfiable-annotator-list-annotators","errorCode":null,"errorMessage":"Unsatisfiable annotator list: ${annotators}","messagePattern":"Unsatisfiable annotator list: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/StanfordCoreNLP.java","lineNumber":546,"sourceCode":"          // Weird hack to replace POS with POS tags from PARSE if we are already doing parse (and just parse)\n          if (useParseForPos && Annotator.STANFORD_POS.equals(prereq)) {\n            prereq = Annotator.STANFORD_PARSE;\n          }\n          if (!prereq.equals(candidate) && !orderedAnnotators.contains(prereq)) {\n            canAdd = false;\n            break;\n          }\n        }\n        // If so, add the annotator\n        if (canAdd) {\n          orderedAnnotators.add(candidate);\n          iter.remove();\n          somethingAdded = true;\n        }\n      }\n      // Make sure we're making progress every iteration, to prevent an infinite loop\n      if (!somethingAdded) {\n        throw new IllegalArgumentException(\"Unsatisfiable annotator list: \" + StringUtils.join(annotators, \",\"));\n      }\n    }\n\n    // Remove depparse + parse -- these are redundant\n    if (orderedAnnotators.contains(STANFORD_PARSE) && !ArrayUtils.contains(annotators, STANFORD_DEPENDENCIES)) {\n      orderedAnnotators.remove(STANFORD_DEPENDENCIES);\n    }\n\n    // Tweak the properties, if necessary\n    // (set the mention annotator to use dependency trees, if appropriate)\n    if ((orderedAnnotators.contains(Annotator.STANFORD_COREF_MENTION) || orderedAnnotators.contains(Annotator.STANFORD_COREF))\n        && !orderedAnnotators.contains(Annotator.STANFORD_PARSE) &&\n        !props.containsKey(\"coref.md.type\")) {\n      props.setProperty(\"coref.md.type\", \"dep\");\n    }\n    // (ensure regexner is after ner)\n    if (orderedAnnotators.contains(Annotator.STANFORD_NER) && orderedAnnotators.contains(STANFORD_REGEXNER)) {\n      orderedAnnotators.remove(STANFORD_REGEXNER);","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/StanfordCoreNLP.java#L528-L564","documentation":"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'.","triggerScenarios":"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.","commonSituations":"Hand-trimming 'annotators' to speed up pipelines and accidentally removing prerequisites like tokenize/ssplit/pos; combining annotators whose requirements conflict in the given order.","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."],"exampleFix":"// before\nprops.setProperty(\"annotators\", \"ner,coref\"); // prerequisites missing\n// after\nprops.setProperty(\"annotators\", \"tokenize,ssplit,pos,lemma,ner,coref\");","handlingStrategy":"validation","validationCode":"List<String> req = new ArrayList<>(Arrays.asList(\"tokenize\",\"ssplit\",\"pos\",\"lemma\"));\nfor (String a : requested) if (!req.contains(a)) req.add(a);\nprops.setProperty(\"annotators\", String.join(\",\", req));","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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."],"tags":["java","annotators","configuration","dependency-resolution"],"backgroundTag":"invalid-config-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}