{"record":{"id":"766a1c18c16a7a7a","repo":"stanfordnlp/CoreNLP","slug":"cannot-find-head-word-of-empty-span","errorCode":null,"errorMessage":"Cannot find head word of empty span!","messagePattern":"Cannot find head word of empty span!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/simple/SentenceAlgorithms.java","lineNumber":241,"sourceCode":"   * The keyphrases of the sentence, using the words of the sentence to convert a span into a keyphrase.\n   * @return A list of String keyphrases in the sentence.\n   *\n   * @see edu.stanford.nlp.simple.SentenceAlgorithms#keyphraseSpans()\n   */\n  public List<String> keyphrases() {\n    return keyphrases(Sentence::words);\n  }\n\n  /**\n   * Get the index of the head word for a given span, based off of the dependency parse.\n   *\n   * @param tokenSpan The span of tokens we are finding the head of.\n   * @return The head index of the given span of tokens.\n   */\n  public int headOfSpan(Span tokenSpan) {\n    // Error checks\n    if (tokenSpan.size() == 0) {\n      throw new IllegalArgumentException(\"Cannot find head word of empty span!\");\n    }\n    List<Optional<Integer>> governors = sentence.governors();\n    if (tokenSpan.start() >= governors.size()) {\n      throw new IllegalArgumentException(\"Span is out of range: \" + tokenSpan + \"; sentence: \" + sentence);\n    }\n    if (tokenSpan.end() > governors.size()) {\n      throw new IllegalArgumentException(\"Span is out of range: \" + tokenSpan + \"; sentence: \" + sentence);\n    }\n\n    // Find where to start searching up the dependency tree\n    int candidateStart = tokenSpan.end() - 1;\n    Optional<Integer> parent;\n    while ( !(parent = governors.get(candidateStart)).isPresent() ) {\n      candidateStart -= 1;\n      if (candidateStart < tokenSpan.start()) {\n        // Case: nothing in this span has a head. Default to right-most element.\n        return tokenSpan.end() - 1;\n      }","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/simple/SentenceAlgorithms.java#L223-L259","documentation":"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.","triggerScenarios":"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.","commonSituations":"Programmatically constructing spans from token offsets with an off-by-one error; filtering spans and not removing zero-length ones before calling headOfSpan.","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"],"exampleFix":"// before\nint head = algorithms.headOfSpan(span);\n// after\nint head = span.size() == 0 ? -1 : algorithms.headOfSpan(span);","handlingStrategy":"validation","validationCode":"if (span != null && span.size() > 0\n    && span.end() <= sentence.length()) {\n  int head = sentence.algorithms().headOfSpan(span);\n}","typeGuard":"boolean isValidSpan(Span s, Sentence sentence) {\n  return s != null && s.size() > 0 && s.start() >= 0 && s.end() <= sentence.length();\n}","tryCatchPattern":"try {\n  int head = algorithms.headOfSpan(span);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"empty span\")) {\n    head = -1;\n  } else { throw e; }\n}","preventionTips":["Filter zero-length spans before processing","Validate span construction arithmetic (start < end)","Add span validity assertions where spans are produced"],"tags":["corenlp","span","precondition"],"backgroundTag":"empty-required-field","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}