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
- Check span.size() > 0 before calling headOfSpan
- Fix the upstream span construction so spans always cover at least one token
- 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
- Filter zero-length spans before processing
- Validate span construction arithmetic (start < end)
- Add span validity assertions where spans are produced
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
- Span is out of range:
- adjustFinalToken: Unexpected final char: |
- allSentences != allWords
- annotator " " requires annotation " ". The usual…
- Array must be sorted!
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)