stanfordnlp/CoreNLP · error · RuntimeException

dependenciesToCoNLLXString: CoreMap does not have required…

Error message

dependenciesToCoNLLXString: CoreMap does not have required TokensAnnotation.

What it means

dependenciesToCoNLLXString serializes a list of TypedDependencies back to CoNLL-X format, which requires the original token texts, tags, and indices. It reads the tokens from the given CoreMap's TokensAnnotation; if the sentence was never tokenized/annotated, tokens is null and the method throws this RuntimeException.

Solutions

  1. Run tokenization before serializing: include 'tokenize' in the StanfordCoreNLP pipeline or call the tokenizer so TokensAnnotation is set.
  2. If constructing the Annotation manually, put a List<CoreLabel> under CoreAnnotations.TokensAnnotation.class.
  3. Use the Sentence/CoreMap returned by a full pipeline (e.g. from CoreDocument tokens) rather than an empty shell object.

Example fix

// before
Annotation sentence = new Annotation(text);
String conll = GrammaticalStructureConversionUtils.dependenciesToCoNLLXString(deps, sentence);
// after
Annotation sentence = new Annotation(text);
new StanfordCoreNLP(new Properties() {{ setProperty("annotators", "tokenize,ssplit"); }}).annotate(sentence);
String conll = GrammaticalStructureConversionUtils.dependenciesToCoNLLXString(deps, sentence);
Defensive patterns

Strategy: validation

Validate before calling

List<CoreLabel> tokens = sentence.get(CoreAnnotations.TokensAnnotation.class);
if (tokens == null || tokens.isEmpty()) {
  throw new IllegalStateException("Sentence must be tokenized before dependenciesToCoNLLXString");
}

Try / catch

try {
  String conll = dependenciesToCoNLLXString(deps, sentence);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("TokensAnnotation")) {
    pipeline.annotate(sentence); // lazily tokenize
    conll = dependenciesToCoNLLXString(deps, sentence);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling dependenciesToCoNLLXString(deps, sentence) with a CoreMap (Sentence/Annotation) that lacks CoreAnnotations.TokensAnnotation — e.g. an Annotation created manually without running tokenization, or a Sentence built without tokens.

Common situations: Building an Annotation by hand for testing; passing only a parse result without the tokenized document; running the serializer on a pipeline output where the tokenize step was disabled.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/trees/GrammaticalStructureConversionUtils.java:91

   * Returns a dependency tree in CoNNL-X format.
   * It requires a CoreMap for the sentence with a TokensAnnotation.
   * Each token has to contain a word and a POS tag.
   *
   * @param deps The list of TypedDependency relations.
   * @param sentence The corresponding CoreMap for the sentence.
   * @return Dependency tree in CoNLL-X format.
   */
  public static String dependenciesToCoNLLXString(Collection<TypedDependency> deps, CoreMap sentence) {
    StringBuilder bf = new StringBuilder();

    HashMap<Integer, TypedDependency> indexedDeps = new HashMap<>(deps.size());
    for (TypedDependency dep : deps) {
      indexedDeps.put(dep.dep().index(), dep);
    }

    List<CoreLabel> tokens = sentence.get(CoreAnnotations.TokensAnnotation.class);
    if (tokens == null) {
      throw new RuntimeException("dependenciesToCoNLLXString: CoreMap does not have required TokensAnnotation.");
    }
    int idx = 1;

    for (CoreLabel token : tokens) {
      String word = token.value();
      String pos = token.tag();
      String cPos = (token.get(CoreAnnotations.CoarseTagAnnotation.class) != null) ?
          token.get(CoreAnnotations.CoarseTagAnnotation.class) : pos;
      String lemma = token.lemma() != null ? token.lemma() : "_";
      Integer gov = indexedDeps.containsKey(idx) ? indexedDeps.get(idx).gov().index() : 0;
      String reln = indexedDeps.containsKey(idx) ? indexedDeps.get(idx).reln().toString() : "erased";
      String out = String.format("%d\t%s\t%s\t%s\t%s\t_\t%d\t%s\t_\t_\n", idx, word, lemma, cPos, pos, gov, reln);
      bf.append(out);
      idx++;
    }
    return bf.toString();
  }

View on GitHub (pinned to 1b7edd19c4)