stanfordnlp/CoreNLP · error · IllegalArgumentException

Word " + wordCount + " (\"" +…

Error message

Word " + wordCount + " (\"" + token.get(CoreAnnotations.TextAnnotation.class) + "\") has a blank answer

What it means

During CRF training, every training token must carry a non-null, non-empty AnswerAnnotation label, because the classIndex of possible labels is built from these answers. A token without a label makes the training data ill-formed, so an IllegalArgumentException naming the word index and text is thrown.

Solutions

  1. Set an answer label on every training token: token.set(CoreAnnotations.AnswerAnnotation.class, label) before training.
  2. Fix the input reader so the gold-label column maps to the 'answer' field (check the column mapping in your training properties, e.g. map=0=word,1=answer).
  3. Pre-validate the training corpus: scan all docs and fail fast on any token with a blank answer, then repair the source data.

Example fix

// before
for (CoreLabel tok : doc) { docOut.add(tok); } // answer never set
// after
for (CoreLabel tok : doc) {
  if (tok.get(CoreAnnotations.AnswerAnnotation.class) == null)
    tok.set(CoreAnnotations.AnswerAnnotation.class, goldLabel);
  docOut.add(tok);
}
Defensive patterns

Strategy: validation

Validate before calling

for (List<IN> doc : trainingDocs) {
  int i = 0;
  for (IN tok : doc) {
    String ans = tok.get(CoreAnnotations.AnswerAnnotation.class);
    if (ans == null || ans.isEmpty())
      throw new IllegalStateException("Token " + i + " (" + tok.get(CoreAnnotations.TextAnnotation.class) + ") has blank answer");
    i++;
  }
}

Try / catch

try {
  classifier.train(trainingDocs);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("has a blank answer")) {
    log.severe("Training data has unlabeled tokens: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling train()/trainSeqModel (via the CRFClassifier constructor path shown) on a List<IN> document where any CoreLabel lacks CoreAnnotations.AnswerAnnotation (answer field), or has answer set to "".

Common situations: Building training documents programmatically and forgetting to setAnswer(); reading CoNLL/TSV files where some rows have no gold label column; filtering that drops labels; sentence boundaries misparsed so unlabeled tokens slip in.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/ie/crf/CRFClassifier.java:732

    int wordCount = 0;

    if (flags.labelDictionaryCutoff > 0) {
      this.labelDictionary = new LabelDictionary();
    }

    for (List<IN> doc : ob) {
      if (flags.useReverse) {
        Collections.reverse(doc);
      }

      // create the full set of labels in classIndex
      // note: update to use addAll later
      for (IN token : doc) {
        wordCount++;
        String ans = token.get(CoreAnnotations.AnswerAnnotation.class);
        if (ans == null || ans.isEmpty()) {
          throw new IllegalArgumentException("Word " + wordCount + " (\"" + token.get(CoreAnnotations.TextAnnotation.class) + "\") has a blank answer");
        }
        classIndex.add(ans);
        if (labelDictionary != null) {
          String observation = token.get(CoreAnnotations.TextAnnotation.class);
          labelDictionary.increment(observation, ans);
        }
      }

      for (int j = 0, docSize = doc.size(); j < docSize; j++) {
        CRFDatum<Collection<String>, CRFLabel> d = makeDatum(doc, j, featureFactories);
        labelIndex.add(d.label());

        List<Collection<String>> features = d.asFeatures();
        for (int k = 0, fSize = features.size(); k < fSize; k++) {
          Collection<String> cliqueFeatures = features.get(k);
          if (k < 2 && flags.removeBackgroundSingletonFeatures) {
            String ans = doc.get(j).get(CoreAnnotations.AnswerAnnotation.class);
            boolean background = ans.equals(flags.backgroundSymbol);

View on GitHub (pinned to 1b7edd19c4)