antlr/antlr4 · error · NotSupportedException

seek to index outside buffer: ${index} not in ${bufferStartI

Error message

seek to index outside buffer: ${index} not in ${bufferStartIndex}..${bufferStartIndex+n}

What it means

After Seek() syncs forward (Sync(index - currentTokenIndex) then clamps index to bufferStartIndex + n - 1), the offset i = index - bufferStartIndex must satisfy i < n. NotSupportedException 'seek to index outside buffer' means the requested absolute index is at or past the last buffered token — typically because EOF was reached so Sync could not extend the buffer further.

Source

Thrown at runtime/CSharp/src/UnbufferedTokenStream.cs:347

            {
                return;
            }
            if (index > currentTokenIndex)
            {
                Sync(index - currentTokenIndex);
                index = Math.Min(index, GetBufferStartIndex() + n - 1);
            }
            int bufferStartIndex = GetBufferStartIndex();
            int i = index - bufferStartIndex;
            if (i < 0)
            {
                throw new ArgumentException("cannot seek to negative index " + index);
            }
            else
            {
                if (i >= n)
                {
                    throw new NotSupportedException("seek to index outside buffer: " + index + " not in " + bufferStartIndex + ".." + (bufferStartIndex + n));
                }
            }
            p = i;
            currentTokenIndex = index;
            if (p == 0)
            {
                lastToken = lastTokenBufferStart;
            }
            else
            {
                lastToken = tokens[p - 1];
            }
        }

        public virtual int Size
        {
            get
            {

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Clamp the target before seeking: index = Math.Min(index, stream.GetBufferStartIndex() + bufferedCount - 1)
  2. Verify more input actually exists (the token at the index is not EOF) before seeking to it
  3. Use CommonTokenStream and check index < stream.Size when full-input random access is required
  4. Audit custom error-handling code that extrapolates indices past the last fetched token

Example fix

// before
stream.Seek(targetIndex); // throws if targetIndex is past last buffered token at EOF

// after
int last = stream.GetBufferStartIndex() + n_buffered - 1;
stream.Seek(Math.Min(targetIndex, last));
Defensive patterns

Strategy: validation

Validate before calling

// C#: clamp the target to the last buffered token before seeking
int lastBuffered = stream.GetBufferStartIndex() + bufferedCount - 1; // bufferedCount = n, or count via LT(k) until EOF
int safeIndex = Math.Min(targetIndex, lastBuffered);
stream.Seek(safeIndex);

Try / catch

try { stream.Seek(targetIndex); } catch (NotSupportedException ex) when (ex.Message.Contains("outside buffer")) { // input exhausted: EOF reached, no token exists at targetIndex; treat as unexpected end of input }

Prevention

When it happens

Trigger: Seek(index) with index beyond bufferStartIndex + n - 1 when the lexer has hit EOF (Sync stops fetching); seeking past the end of input; computing an index from token.StopIndex+1 on the EOF token and seeking to it.

Common situations: Error recovery or custom parsing logic that seeks to 'nextTokenIndex + k' without checking whether input remains; tests with truncated input where the parser assumes more tokens exist; off-by-one when converting absolute token indices to buffer offsets.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/a4ce011427d8df4b. Report an issue: GitHub.