stanfordnlp/CoreNLP · warning · IllegalStateException
Comparing a mention with itself for representativeness
Error message
Comparing a mention with itself for representativeness
What it means
Mention.moreRepresentativeThan (representativeness comparison) throws IllegalStateException when two mentions have identical originalSpan sizes but neither comparison branch returned — i.e., the method was effectively called comparing a mention with itself (or a mention with equal-size spans through a path assumed impossible). The class treats this as an unreachable internal state.
Solutions
- Ensure cluster representative selection never compares a mention with itself (skip identity references / use i < j ordering)
- Check for and deduplicate identical Mentions added to the same CorefCluster
- If you patched the comparison logic, restore tie-breaker branches so equal-size mentions resolve before the final else
- Upgrade to an unmodified CoreNLP version to rule out fork-introduced regressions
Example fix
// before if (m1.moreRepresentativeThan(m2)) rep = m1; // can hit m1 == m2 // after if (m1 != m2 && m1.moreRepresentativeThan(m2)) rep = m1;
Defensive patterns
Strategy: try-catch
Validate before calling
if (m1 == m2) throw new IllegalArgumentException("Cannot compare a mention with itself");
if (m1.originalSpan.size() == m2.originalSpan.size())
throw new IllegalArgumentException("Ambiguous representative: equal-size spans"); Try / catch
try {
if (m1.moreRepresentativeThan(m2)) rep = m1; else rep = m2;
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Comparing a mention with itself")) {
rep = m1; // already the representative; keep as-is
} else throw e;
} Prevention
- Skip identity comparisons (m1 != m2) when choosing cluster representatives
- Deduplicate Mentions before building CorefClusters
- Do not modify tie-breaker branches in moreRepresentativeThan when forking
- Use i < j index ordering when scanning pairs in a cluster
When it happens
Trigger: Calling moreRepresentativeThan on two Mention objects with the same originalSpan size in a code path where all earlier tie-breakers (sentence position, head, NE, etc.) also tie — typically m.moreRepresentativeThan(m) or duplicate mentions.
Common situations: Duplicate mentions generated by custom extraction producing the same mention twice in a cluster; patched coref algorithm code that compares a mention against itself when picking cluster representatives; modified tie-breaker conditions removing the original distinctness guarantees.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- check flag in markMentionRelation…
- Invalid start index =-: originalSpan=[], head=
- edu.stanford.nlp.coref.CorefScorer.ScorerMissingException
- Error initializing coref system
- Error making document
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/ce11d79eec36bda4.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/coref/data/Mention.java:1144
// Ensure that both NER tags are neither MISC nor O, or are both not existent
assert nerString == null || nerString.equals(m.nerString) || (!nerString.equals("O") && !nerString.equals("MISC") && !m.nerString.equals("O") && !m.nerString.equals("MISC"));
// Return larger headIndex - startIndex
if (headIndex - startIndex > m.headIndex - m.startIndex) { return true; }
else if (headIndex - startIndex < m.headIndex - m.startIndex) { return false; }
// Return earlier sentence number
else if (sentNum < m.sentNum) { return true; }
else if (sentNum > m.sentNum) { return false; }
// Return earlier head index
else if (headIndex < m.headIndex) { return true; }
else if (headIndex > m.headIndex) { return false; }
// If the mentions are short, take the longer one
else if (originalSpan.size() <= 5 && originalSpan.size() > m.originalSpan.size()) { return true; }
else if (originalSpan.size() <= 5 && originalSpan.size() < m.originalSpan.size()) { return false; }
// If the mentions are long, take the shorter one (we're getting into the realm of nonsense by here)
else if (originalSpan.size() < m.originalSpan.size()) { return true; }
else if (originalSpan.size() > m.originalSpan.size()) { return false; }
else {
throw new IllegalStateException("Comparing a mention with itself for representativeness");
}
}
}
// Returns filtered premodifiers (no determiners or numerals)
public ArrayList<ArrayList<IndexedWord>> getPremodifiers(){
ArrayList<ArrayList<IndexedWord>> premod = new ArrayList<>();
if(headIndexedWord == null) return premod;
for(Pair<GrammaticalRelation,IndexedWord> child : enhancedDependency.childPairs(headIndexedWord)){
String function = child.first().getShortName();
if(child.second().index() < headWord.index()
&& !child.second.tag().equals("DT") && !child.second.tag().equals("WRB")
&& !function.endsWith("det") && !function.equals("nummod")
&& !function.startsWith("acl") && !function.startsWith("advcl")
&& !function.equals("punct")){
ArrayList<IndexedWord> phrase = new ArrayList<>(enhancedDependency.descendants(child.second()));View on GitHub (pinned to 1b7edd19c4)