{"record":{"id":"63f8380561b21b66","repo":"ssssssss-team/spider-flow","slug":"the-two-spans-do-not-reference-the-same-source","errorCode":null,"errorMessage":"The two spans do not reference the same source.","messagePattern":"The two spans do not reference the same source\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spider-flow-core/src/main/java/org/spiderflow/core/expression/parsing/Span.java","lineNumber":36,"sourceCode":"\tpublic Span (String source) {\n\t\tthis(source, 0, source.length());\n\t}\n\n\tpublic Span (String source, int start, int end) {\n\t\tif (start > end) throw new IllegalArgumentException(\"Start must be <= end.\");\n\t\tif (start < 0) throw new IndexOutOfBoundsException(\"Start must be >= 0.\");\n\t\tif (start > source.length() - 1) \n\t\t\tthrow new IndexOutOfBoundsException(\"Start outside of string.\");\n\t\tif (end >source.length()) throw new IndexOutOfBoundsException(\"End outside of string.\");\n\n\t\tthis.source = source;\n\t\tthis.start = start;\n\t\tthis.end = end;\n\t\tthis.cachedText = source.substring(start, end);\n\t}\n\n\tpublic Span (Span start, Span end) {\n\t\tif (!start.source.equals(end.source)) throw new IllegalArgumentException(\"The two spans do not reference the same source.\");\n\t\tif (start.start > end.end) throw new IllegalArgumentException(\"Start must be <= end.\");\n\t\tif (start.start < 0) throw new IndexOutOfBoundsException(\"Start must be >= 0.\");\n\t\tif (start.start > start.source.length() - 1) throw new IndexOutOfBoundsException(\"Start outside of string.\");\n\t\tif (end.end > start.source.length()) throw new IndexOutOfBoundsException(\"End outside of string.\");\n\n\t\tthis.source = start.source;\n\t\tthis.start = start.start;\n\t\tthis.end = end.end;\n\t\tthis.cachedText = source.substring(this.start, this.end);\n\t}\n\n\t/** Returns the text referenced by this span **/\n\tpublic String getText () {\n\t\treturn cachedText;\n\t}\n\n\t/** Returns the index of the first character of this span. **/\n\tpublic int getStart () {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/ssssssss-team/spider-flow/blob/c799cca99c7d064673dc79e6ef06a08bbc0e292d/spider-flow-core/src/main/java/org/spiderflow/core/expression/parsing/Span.java#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nSpan span = new Span(tokenStart, tokenEnd); // tokens from different parses\n// after\nif (!tokenStart.source.equals(tokenEnd.source)) throw new IllegalStateException(\"spans from different sources\");\nSpan span = new Span(tokenStart, tokenEnd);","handlingStrategy":"validation","validationCode":"if (!startSpan.source.equals(endSpan.source)) throw new IllegalStateException(\"spans reference different sources\");\nSpan span = new Span(startSpan, endSpan);","typeGuard":"boolean sameSource(Span a, Span b) {\n    return a != null && b != null && a.source.equals(b.source);\n}","tryCatchPattern":"try {\n    Span span = new Span(startSpan, endSpan);\n} catch (IllegalArgumentException e) {\n    throw new IllegalStateException(\"start/end spans come from different parse runs: \" + e.getMessage());\n}","preventionTips":["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."],"tags":["parsing","span","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"c799cca99c7d064673dc79e6ef06a08bbc0e292d","analyzedAt":"2026-09-08T13:47:08.225Z","contentChangedAt":"2026-09-08T13:47:08.225Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}