antlr/antlr4 · error · UnsupportedOperationException
seek to index outside buffer: {index} not in {bufferStartInd
Error message
seek to index outside buffer: {index} not in {bufferStartIndex}..{bufferStartIndex+n} What it means
UnbufferedCharStream.seek(index) throws UnsupportedOperationException when the computed offset lands at or beyond the number of buffered characters (i >= n). Forward seeks sync() first and clamp to the last available index, so this fires mainly on backward seeks whose target is inside the window arithmetic but outside the actual data, or on defensive edge cases when the buffer cannot satisfy the request (e.g., seeking far past EOF with an exhausted source).
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java:294
*/
@Override
public void seek(int index) {
if (index == currentCharIndex) {
return;
}
if (index > currentCharIndex) {
sync(index - currentCharIndex);
index = Math.min(index, getBufferStartIndex() + n - 1);
}
// index == to bufferStartIndex should set p to 0
int i = index - getBufferStartIndex();
if ( i < 0 ) {
throw new IllegalArgumentException("cannot seek to negative index " + index);
}
else if (i >= n) {
throw new UnsupportedOperationException("seek to index outside buffer: "+
index+" not in "+getBufferStartIndex()+".."+(getBufferStartIndex()+n));
}
p = i;
currentCharIndex = index;
if (p == 0) {
lastChar = lastCharBufferStart;
}
else {
lastChar = data[p-1];
}
}
@Override
public int size() {
throw new UnsupportedOperationException("Unbuffered stream cannot know its size");
}
View on GitHub (pinned to 7d5770395b)
Solutions
- Clamp the target to the last valid index before seeking: index = Math.min(index, lastIndexKnown)
- Verify the target is within the marked/retained window and at or before EOF before calling seek
- Use a buffered stream if you need position-jump semantics on the whole input
Example fix
// before
stream.seek(requestedOffset); // may land past buffered data / EOF
// after
int last = stream.getBufferStartIndex() + /* buffered count via LA probing */ 0;
// safer: only seek within a held mark's window
int m = stream.mark();
try {
int target = Math.min(requestedOffset, stream.index());
stream.seek(target);
} finally { stream.release(m); } Defensive patterns
Strategy: validation
Validate before calling
int target = Math.min(requestedIndex, lastKnownIndex); // clamp to at-or-before EOF
if (target < stream.index()) {
// backward seek: ensure within the retained window (see error 52 guard)
}
stream.seek(target); Try / catch
try { stream.seek(target); }
catch (UnsupportedOperationException e) { /* clamp target into the buffer window and retry once */ } Prevention
- Clamp seek targets to known-valid indexes before calling
- Validate user-supplied offsets against input length before seeking
- Prefer relative consumption over absolute seeks on unbuffered streams
When it happens
Trigger: seek(target) where target exceeds the end of the stream after sync has buffered EOF; seeking while the buffer is empty or was reset concurrently; index arithmetic that skips the early-return and clamp paths.
Common situations: Calling seek with a user-supplied offset that assumes the input is longer than it is; progress reporting code seeking to percentage positions in the stream.
Related errors
- cannot seek to negative index {index}
- cannot consume EOF
- cannot consume EOF
- release() called with an invalid marker.
- the interval extends past the end of the stream
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/c80023c8a7ddaac4.
Report an issue: GitHub.