ssssssss-team/spider-flow · error · IllegalArgumentException
The two spans do not reference the same source.
Error message
The two spans do not reference the same source.
What it means
The Span(Span,Span) constructor builds a new span from a start span and an end span, but both must reference the exact same source string (compared with equals). If the two source strings differ, it throws IllegalArgumentException("The two spans do not reference the same source."). This ensures the resulting span denotes a coherent region of one document.
Solutions
- Ensure both spans are derived from the same, unchanged source string.
- Fix the parse pipeline so the end span comes from the same parser instance/input as the start span.
- If the text changed, re-parse and rebuild both spans from the new source.
- Identity-check the sources (start.source.equals(end.source)) before combining.
Example fix
// before
Span span = new Span(tokenStart, tokenEnd); // tokens from different parses
// after
if (!tokenStart.source.equals(tokenEnd.source)) throw new IllegalStateException("spans from different sources");
Span span = new Span(tokenStart, tokenEnd); Defensive patterns
Strategy: validation
Validate before calling
if (!startSpan.source.equals(endSpan.source)) throw new IllegalStateException("spans reference different sources");
Span span = new Span(startSpan, endSpan); Type guard
boolean sameSource(Span a, Span b) {
return a != null && b != null && a.source.equals(b.source);
} Try / catch
try {
Span span = new Span(startSpan, endSpan);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("start/end spans come from different parse runs: " + e.getMessage());
} Prevention
- Keep start and end spans from one Parser/TokenStream instance only.
- Never combine spans across re-parses after the source text changed.
- Carry the source string alongside tokens so provenance is checkable.
- Add a same-source assertion in helper methods that merge spans.
When it happens
Trigger: Calling new Span(startSpan, endSpan) where startSpan.source and endSpan.source are different String instances with different content — e.g. spans created from two separately parsed expressions or two versions of the same text.
Common situations: Combining tokens from different parser runs; the source text was re-generated between creating the start and end spans (content changed, so equals fails); mixing spans from include/evaluated sub-sources.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Start must be <= end.
- Start must be >= 0.
- Start outside of string.
- End outside of string.
- Start must be <= end.
AI-assisted analysis of ssssssss-team/spider-flow@c799cca99c (2026-09-08).
Data as JSON: /api/errors/63f8380561b21b66.
Report an issue: GitHub.
Appendix: source
Thrown at spider-flow-core/src/main/java/org/spiderflow/core/expression/parsing/Span.java:36
public Span (String source) {
this(source, 0, source.length());
}
public Span (String source, int start, int end) {
if (start > end) throw new IllegalArgumentException("Start must be <= end.");
if (start < 0) throw new IndexOutOfBoundsException("Start must be >= 0.");
if (start > source.length() - 1)
throw new IndexOutOfBoundsException("Start outside of string.");
if (end >source.length()) throw new IndexOutOfBoundsException("End outside of string.");
this.source = source;
this.start = start;
this.end = end;
this.cachedText = source.substring(start, end);
}
public Span (Span start, Span end) {
if (!start.source.equals(end.source)) throw new IllegalArgumentException("The two spans do not reference the same source.");
if (start.start > end.end) throw new IllegalArgumentException("Start must be <= end.");
if (start.start < 0) throw new IndexOutOfBoundsException("Start must be >= 0.");
if (start.start > start.source.length() - 1) throw new IndexOutOfBoundsException("Start outside of string.");
if (end.end > start.source.length()) throw new IndexOutOfBoundsException("End outside of string.");
this.source = start.source;
this.start = start.start;
this.end = end.end;
this.cachedText = source.substring(this.start, this.end);
}
/** Returns the text referenced by this span **/
public String getText () {
return cachedText;
}
/** Returns the index of the first character of this span. **/
public int getStart () {View on GitHub (pinned to c799cca99c)