antlr/antlr4 · error · UnsupportedOperationException
interval {interval} outside buffer: {bufferStartIndex}..{buf
Error message
interval {interval} outside buffer: {bufferStartIndex}..{bufferStartIndex+n-1} What it means
UnbufferedCharStream.getText(Interval) throws UnsupportedOperationException when any part of the requested interval lies outside the retained buffer window (interval.a < bufferStartIndex or interval.b >= bufferStartIndex + n). Characters before the window were already discarded and cannot be re-read; this is the unbuffered design trade-off, so it is unsupported rather than an invalid argument.
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java:336
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());
}
protected final int getBufferStartIndex() {
return currentCharIndex - p;
}
}
View on GitHub (pinned to 7d5770395b)
Solutions
- Extract text eagerly during the parse (in enterRule/exitRule or via the lexer) while it is still inside the window
- Hold a mark() from before the earliest text you will need and release it after extraction
- Use a buffered stream (ANTLRInputStream/CharStreams.fromPath) if late text extraction is unavoidable
Example fix
// before
parser.buildParseTree = true;
new ParseTreeWalker().walk(listener, tree);
// listener later calls ctx.getText() -> chars already discarded -> throws
// after
// extract needed text during the parse:
class MyListener extends MyParserBaseListener {
@Override public void exitEveryRule(ParserRuleContext ctx) {
record(ctx, tokens.getText(ctx)); // while window still covers ctx
}
} Defensive patterns
Strategy: validation
Validate before calling
int bufferStart = /* track via marks, or compute as index() - p equivalent */ floorIndex;
if (interval.a < floorIndex) {
text = previouslyExtracted.get(interval); // cache text eagerly during parse
} else {
text = stream.getText(interval);
} Try / catch
try { stream.getText(interval); }
catch (UnsupportedOperationException e) { /* fall back to cached text captured during the parse */ } Prevention
- Extract text eagerly during the parse, not in post-passes
- Hold marks over ranges you will query later
- Use a buffered stream when late text extraction is a requirement
When it happens
Trigger: Calling getText for a range parsed long ago after the window advanced (e.g., in a parse-tree listener or after parsing finishes); requesting text behind the current mark horizon; token text extraction deferred until after the parse.
Common situations: Post-parse tree walking that calls ctx.getText() or token text lookups on large inputs; error reporting that quotes earlier lines; switching from ANTLRInputStream to UnbufferedCharStream without auditing text lookups.
Related errors
- invalid interval
- the interval extends past the end of the stream
- release() called with an invalid marker.
- cannot seek to negative index {index}
- seek to index outside buffer: {index} not in {bufferStartInd
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/c8b9ecfacfa04391.
Report an issue: GitHub.