antlr/antlr4 · error · IllegalArgumentException
invalid interval
Error message
invalid interval
What it means
UnbufferedCharStream.getText(Interval) first validates the interval itself: interval.a must be >= 0 and interval.b must be at least a-1 (an empty interval starting at a is legal). Any negative start or end more than one before the start is rejected as 'invalid interval' with IllegalArgumentException.
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java:325
@Override
public int size() {
throw new UnsupportedOperationException("Unbuffered stream cannot know its size");
}
@Override
public String getSourceName() {
if (name == null || name.isEmpty()) {
return UNKNOWN_SOURCE_NAME;
}
return name;
}
@Override
public String getText(Interval interval) {
if (interval.a < 0 || interval.b < interval.a - 1) {
throw new IllegalArgumentException("invalid interval");
}
int bufferStartIndex = getBufferStartIndex();
if (n > 0 && data[n - 1] == Character.MAX_VALUE) {
if (interval.a + interval.length() > bufferStartIndex + n) {
throw new IllegalArgumentException("the interval extends past the end of the stream");
}
}
if (interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n) {
throw new UnsupportedOperationException("interval "+interval+" outside buffer: "+
bufferStartIndex+".."+(bufferStartIndex+n-1));
}
// convert from absolute to local index
int i = interval.a - bufferStartIndex;
return new String(data, i, interval.length());
}
View on GitHub (pinned to 7d5770395b)
Solutions
- Normalize the interval before calling: a >= 0 and b = Math.max(b, a - 1)
- Skip text extraction for contexts whose start/stop tokens are EOF or have negative indexes
- Build intervals from real matched tokens (ctx.start, ctx.stop) and null-check them
Example fix
// before
String t = stream.getText(Interval.of(ctx.start.getStartIndex(), ctx.stop.getStartIndex())); // EOF: -1,-1
// after
if (ctx.start == null || ctx.stop == null
|| ctx.start.getStartIndex() < 0 || ctx.stop.getStartIndex() < ctx.start.getStartIndex() - 1) {
return "";
}
String t = stream.getText(Interval.of(ctx.start.getStartIndex(), ctx.stop.getStartIndex())); Defensive patterns
Strategy: validation
Validate before calling
static Interval normalize(int a, int b) {
if (a < 0) return null; // invalid
return Interval.of(a, Math.max(b, a - 1));
}
Interval iv = normalize(start, stop);
if (iv != null) text = stream.getText(iv); Prevention
- Reject EOF/sentinel tokens (negative indexes) before extracting text
- Centralize interval construction in one validated helper
- Treat empty intervals as empty text, not errors
When it happens
Trigger: getText(Interval.of(-1, -1)) or Interval.of(5, 2); intervals built from sentinel tokens whose getStartIndex()/getStopIndex() are -1 (EOF tokens); computing b as startIndex + length - 1 with a length that underflows.
Common situations: Extracting text for a rule context that matched only EOF; error listeners building intervals from invalid tokens; off-by-one arithmetic when constructing intervals from token positions.
Related errors
- the interval extends past the end of the stream
- interval {interval} outside buffer: {bufferStartIndex}..{buf
- index cannot be negative
- ANTLR 4 caught {} build errors.
- cannot consume EOF
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/5be908e022353113.
Report an issue: GitHub.