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
- Check containment first (a.contains(b) || b.contains(a)) and handle overlapping spans separately before calling isBefore
- Trim/narrow one of the spans so they are disjoint before comparison
- Use raw start/end arithmetic instead of isBefore when containment is legitimate in your data
- 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
- Deduplicate and filter nested spans before pairwise ordering
- Add a containment pre-check before any distance/isBefore call
- Document that Span ordering methods require disjoint spans
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
- fromValues() must take an array with 2 elements
- Span must be entirely contained in the sentence:
- Unknown value for span
- Unknown value for span
- addFeature was called with a features object that is…
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)