stanfordnlp/CoreNLP · error · java.lang.IllegalArgumentException

Span " + toString() + " contains otherSpan " + otherSpan +…

Error message

Span " + toString() + " contains otherSpan " + otherSpan + " (or vice versa)

What it means

Span.isBefore(Span) compares spans that are assumed to be strictly ordered (this ends before other starts). If either span contains the other, ordering is undefined, so the method throws IllegalArgumentException naming both spans. It is also called internally by Span.distance.

Solutions

  1. Check containment first (a.contains(b) || b.contains(a)) and handle overlapping spans separately before calling isBefore
  2. Trim/narrow one of the spans so they are disjoint before comparison
  3. Use raw start/end arithmetic instead of isBefore when containment is legitimate in your data
  4. Compare start/end fields directly with explicit semantics for the overlap case

Example fix

// before
int d = spanA.distance(spanB); // throws when one span contains the other
// after
int d = (spanA.contains(spanB) || spanB.contains(spanA)) ? 0 : spanA.distance(spanB);
Defensive patterns

Strategy: validation

Validate before calling

if (a.contains(b) || b.contains(a)) { /* skip or treat distance as 0 */ } else { d = a.distance(b); }

Type guard

static boolean orderable(Span a, Span b) { return !a.contains(b) && !b.contains(a); }

Try / catch

try { return a.isBefore(b); } catch (IllegalArgumentException e) { return false; } // containment case handled explicitly elsewhere

Prevention

When it happens

Trigger: Calling spanA.isBefore(spanB) (directly or via Span.distance) where spanA.contains(spanB) or spanB.contains(spanA), e.g. overlapping/identical token spans like [3,7] and [5,9] or [3,7] and [3,7].

Common situations: Computing distances between extracted relation mentions whose entity spans overlap; comparing annotation spans produced from different tokenizations; accidentally passing the same span twice.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/47ba0e9d8e0b5da8. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/ie/machinereading/structure/Span.java:127

  public boolean contains(Span otherSpan) {
    return this.start <= otherSpan.start && otherSpan.end <= this.end;
  }
  
  /**
   * Returns true if i is inside this span.  Note that the start is inclusive and the end is exclusive.
   */
  public boolean contains(int i) {
    return this.start <= i && i < this.end;
  }

  /**
   * Returns true if this span ends before the otherSpan starts.
   * 
   * @throws IllegalArgumentException if either span contains the other span
   */
  public boolean isBefore(Span otherSpan) {
    if (this.contains(otherSpan) || otherSpan.contains(this)) {
      throw new IllegalArgumentException("Span " + toString() + " contains otherSpan " + otherSpan + " (or vice versa)");
    }
    return this.end <= otherSpan.start;
  }

  /**
   * Returns true if this span starts after the otherSpan's end.
   * 
   * @throws IllegalArgumentException if either span contains the other span
   */
  @SuppressWarnings("UnusedDeclaration")
  public boolean isAfter(Span otherSpan) {
    if (this.contains(otherSpan) || otherSpan.contains(this)) {
      throw new IllegalArgumentException("Span " + toString() + " contains otherSpan " + otherSpan + " (or vice versa)");
    }
    return this.start >= otherSpan.end;
  }

  /**

View on GitHub (pinned to 1b7edd19c4)