ssssssss-team/spider-flow · error · IndexOutOfBoundsException
Start must be >= 0.
Error message
Start must be >= 0.
What it means
Validation guard in the CharacterStream(String source, int start, int end) constructor of the expression-language parser. It fires when the caller supplies a negative start offset (the companion check throws on start > end). The input at fault is a start index below 0, i.e. a malformed slicing window over the expression source string; index would otherwise point before the beginning of the character buffer.
Solutions
- Check the result of indexOf() for -1 before using it as a start index
- Guard with Math.max(0, startIndex) only if clamping is semantically correct
- Log and handle the not-found case explicitly instead of building a stream
Example fix
// before
int start = source.indexOf('{');
new CharacterStream(source, start, source.length());
// after
int start = source.indexOf('{');
if (start < 0) { throw new IllegalArgumentException("No opening brace found"); }
new CharacterStream(source, start, source.length()); Defensive patterns
Strategy: validation
Validate before calling
if (start < 0) throw new IllegalArgumentException("start must be >= 0, got " + start); Try / catch
try {
new CharacterStream(source, start, end);
} catch (IndexOutOfBoundsException e) {
logger.error("Negative start index: {}", start);
} Prevention
- Always check indexOf() results for -1 before using as an index
- Never decrement a start index below 0 without clamping
- Validate all index arithmetic results before constructing streams
When it happens
Trigger: new CharacterStream(source, start, end) with start < 0, typically from indexOf() returning -1 or an unadjusted decrement past 0.
Common situations: Custom tokenizers using String.indexOf results directly without checking for -1.
Related errors
- Start must be <= end.
- Start outside of string.
- End outside of string.
- Start must be <= end.
- Start must be >= 0.
AI-assisted analysis of ssssssss-team/spider-flow@c799cca99c (2026-09-08).
Data as JSON: /api/errors/35d24898e8cbad53.
Report an issue: GitHub.
Appendix: source
Thrown at spider-flow-core/src/main/java/org/spiderflow/core/expression/parsing/CharacterStream.java:21
import javax.xml.transform.Source;
/** Wraps a the content of a {@link Source} and handles traversing the contained characters. Manages a current {@link Span} via
* the {@link #startSpan()} and {@link #endSpan()} methods. */
public class CharacterStream {
private final String source;
private int index = 0;
private final int end;
private int spanStart = 0;
public CharacterStream (String source) {
this(source, 0, source.length());
}
public CharacterStream (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 > Math.max(0, 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.index = start;
this.end = end;
}
/** Returns whether there are more characters in the stream **/
public boolean hasMore () {
return index < end;
}
/** Returns the next character without advancing the stream **/
public char peek () {
if (!hasMore()) throw new RuntimeException("No more characters in stream.");
return source.charAt(index++);
}View on GitHub (pinned to c799cca99c)