stanfordnlp/CoreNLP · error · IllegalArgumentException

Cannot find head word of empty span!

Error message

Cannot find head word of empty span!

What it means

SentenceAlgorithms.headOfSpan(Span) requires a non-empty token span because it must walk up the dependency tree from a token to find the head; an empty span has no starting token, so IllegalArgumentException is thrown. This is a precondition check on the input span.

Solutions

  1. Check span.size() > 0 before calling headOfSpan
  2. Fix the upstream span construction so spans always cover at least one token
  3. Filter out empty spans from a span collection before processing

Example fix

// before
int head = algorithms.headOfSpan(span);
// after
int head = span.size() == 0 ? -1 : algorithms.headOfSpan(span);
Defensive patterns

Strategy: validation

Validate before calling

if (span != null && span.size() > 0
    && span.end() <= sentence.length()) {
  int head = sentence.algorithms().headOfSpan(span);
}

Type guard

boolean isValidSpan(Span s, Sentence sentence) {
  return s != null && s.size() > 0 && s.start() >= 0 && s.end() <= sentence.length();
}

Try / catch

try {
  int head = algorithms.headOfSpan(span);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("empty span")) {
    head = -1;
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling sentence.algorithms().headOfSpan(span) where span.size() == 0, e.g. a Span built with equal start/end indices or produced by an upstream algorithm that returned an empty range.

Common situations: Programmatically constructing spans from token offsets with an off-by-one error; filtering spans and not removing zero-length ones before calling headOfSpan.

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/766a1c18c16a7a7a. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/simple/SentenceAlgorithms.java:241

   * The keyphrases of the sentence, using the words of the sentence to convert a span into a keyphrase.
   * @return A list of String keyphrases in the sentence.
   *
   * @see edu.stanford.nlp.simple.SentenceAlgorithms#keyphraseSpans()
   */
  public List<String> keyphrases() {
    return keyphrases(Sentence::words);
  }

  /**
   * Get the index of the head word for a given span, based off of the dependency parse.
   *
   * @param tokenSpan The span of tokens we are finding the head of.
   * @return The head index of the given span of tokens.
   */
  public int headOfSpan(Span tokenSpan) {
    // Error checks
    if (tokenSpan.size() == 0) {
      throw new IllegalArgumentException("Cannot find head word of empty span!");
    }
    List<Optional<Integer>> governors = sentence.governors();
    if (tokenSpan.start() >= governors.size()) {
      throw new IllegalArgumentException("Span is out of range: " + tokenSpan + "; sentence: " + sentence);
    }
    if (tokenSpan.end() > governors.size()) {
      throw new IllegalArgumentException("Span is out of range: " + tokenSpan + "; sentence: " + sentence);
    }

    // Find where to start searching up the dependency tree
    int candidateStart = tokenSpan.end() - 1;
    Optional<Integer> parent;
    while ( !(parent = governors.get(candidateStart)).isPresent() ) {
      candidateStart -= 1;
      if (candidateStart < tokenSpan.start()) {
        // Case: nothing in this span has a head. Default to right-most element.
        return tokenSpan.end() - 1;
      }

View on GitHub (pinned to 1b7edd19c4)