{"record":{"id":"a230152dad6e92e6","repo":"stanfordnlp/CoreNLP","slug":"invalid-start-index-originalspan-head","errorCode":null,"errorMessage":"Invalid start index =-: originalSpan=[], head=","messagePattern":"Invalid start index =-: originalSpan=\\[\\], head=","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/coref/data/Mention.java","lineNumber":720,"sourceCode":"\n  private static boolean knownSuffix(String s) {\n    if(s.endsWith(\".\")) s = s.substring(0, s.length() - 1);\n    for(String suff: commonNESuffixes){\n      if(suff.equalsIgnoreCase(s)){\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private void setHeadString() {\n    this.headString = headWord.get(CoreAnnotations.TextAnnotation.class).toLowerCase();\n    String ner = headWord.get(CoreAnnotations.NamedEntityTagAnnotation.class);\n    if (ner != null && !ner.equals(\"O\")) {\n      // make sure that the head of a NE is not a known suffix, e.g., Corp.\n      int start = headIndex - startIndex;\n      if (originalSpan.size() > 0 && start >= originalSpan.size()) {\n        throw new RuntimeException(\"Invalid start index \" + start + \"=\" + headIndex + \"-\" + startIndex\n                + \": originalSpan=[\" + StringUtils.joinWords(originalSpan, \" \") + \"], head=\" + headWord);\n      }\n      while (start >= 0) {\n        String head = originalSpan.size() > 0 ? originalSpan.get(start).get(CoreAnnotations.TextAnnotation.class).toLowerCase() : \"\";\n        if (knownSuffix(head)) {\n          start --;\n        } else {\n          this.headString = head;\n          this.headWord = originalSpan.get(start);\n          this.headIndex = startIndex + start;\n          break;\n        }\n      }\n    }\n    this.headIndexedWord = basicDependency.getNodeByIndexSafe(headWord.index());\n  }\n\n  private void setNERString() {","sourceCodeStart":702,"sourceCodeEnd":738,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/coref/data/Mention.java#L702-L738","documentation":"The Mention constructor throws when computing the NE-suffix scan: the head word's offset within originalSpan (headIndex - startIndex) is negative or >= originalSpan.size(), meaning the head word is not inside the mention's original span. This catches a broken span/head alignment early.","triggerScenarios":"Building new Mention(..., originalSpan, headWord, ...) where headIndex < startIndex or headIndex - startIndex >= originalSpan.size(), for a mention whose head word has a NamedEntityTag other than 'O'.","commonSituations":"Custom mention-extraction code computing headIndex from a different token list than originalSpan; off-by-one span construction (end-exclusive vs end-inclusive); downstream tools constructing Mentions from parse output with mismatched indices.","solutions":["Fix the code that sets startIndex/headIndex so headIndex lies within [startIndex, startIndex+originalSpan.size())","Verify originalSpan is built from the same CoreMap token list used for headIndex","Validate mention spans before construction: assert headIndex >= startIndex && headIndex < startIndex + span.size()","If constructing mentions from external parses, recompute headIndex using CoreNLP's head-finder conventions"],"exampleFix":"// before\nint start = headIndex - startIndex;\nMention m = new Mention(..., originalSpan, headWord, ...); // start out of range\n// after\nif (headIndex < startIndex || headIndex - startIndex >= originalSpan.size()) {\n  throw new IllegalArgumentException(\"head outside span: \" + headIndex + \"/\" + startIndex);\n}\nMention m = new Mention(..., originalSpan, headWord, ...);","handlingStrategy":"validation","validationCode":"boolean valid = headIndex >= startIndex\n  && originalSpan.size() > 0\n  && (headIndex - startIndex) < originalSpan.size();\nif (!valid) throw new IllegalArgumentException(\"head word outside mention span\");","typeGuard":null,"tryCatchPattern":"try {\n  Mention m = new Mention(id, sentNum, startIndex, endIndex, animacy, generics, ...);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Invalid start index\")) {\n    logger.severe(\"Head/span misalignment in custom mention extraction: \" + e.getMessage());\n  } else throw e;\n}","preventionTips":["Compute headIndex against the exact same token list used for originalSpan","Use end-exclusive convention consistently when slicing spans","Assert span/head invariants in custom mention-extraction code before construction","Test custom extractors against CoreNLP's own mention extractor output on sample docs"],"tags":["coref","mention","index-out-of-range","data-consistency"],"backgroundTag":"index-out-of-range","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}