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

  1. Ensure cluster representative selection never compares a mention with itself (skip identity references / use i < j ordering)
  2. Check for and deduplicate identical Mentions added to the same CorefCluster
  3. If you patched the comparison logic, restore tie-breaker branches so equal-size mentions resolve before the final else
  4. 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

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


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)