antlr/antlr4 · error · NotSupportedException

interval ${interval} not in token buffer window: ${bufferSta

Error message

interval ${interval} not in token buffer window: ${bufferStartIndex}..${bufferStopIndex}

What it means

UnbufferedTokenStream.GetText(interval) can only render text for tokens still present in its fixed-size window; it throws NotSupportedException when interval.a < bufferStartIndex or interval.b > bufferStartIndex + tokens.Length - 1. Consumed tokens before the window are gone forever, and the window is only as large as the underlying token array.

Source

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

        public virtual string SourceName
        {
            get
            {
                return TokenSource.SourceName;
            }
        }

        [return: NotNull]
        public virtual string GetText(Interval interval)
        {
            int bufferStartIndex = GetBufferStartIndex();
            int bufferStopIndex = bufferStartIndex + tokens.Length - 1;
            int start = interval.a;
            int stop = interval.b;
            if (start < bufferStartIndex || stop > bufferStopIndex)
            {
                throw new NotSupportedException("interval " + interval + " not in token buffer window: " + bufferStartIndex + ".." + bufferStopIndex);
            }
            int a = start - bufferStartIndex;
            int b = stop - bufferStartIndex;
            StringBuilder buf = new StringBuilder();
            for (int i = a; i <= b; i++)
            {
                IToken t = tokens[i];
                buf.Append(t.Text);
            }
            return buf.ToString();
        }

        protected internal int GetBufferStartIndex()
        {
            return currentTokenIndex - p;
        }
    }
}

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Use CommonTokenStream when token text may be requested for arbitrary past intervals
  2. Capture GetText for a rule's interval inside its exit listener/listener callback, while the tokens are guaranteed still inside the window
  3. Before calling, verify interval.a >= GetBufferStartIndex() and interval.b <= bufferStartIndex + tokens.Length - 1, and skip or re-lex otherwise

Example fix

# before (Python-equivalent API usage pattern)
# tokens = UnbufferedTokenStream(lexer); parser error listener calls:
text = tokens.GetText(Interval(oldStart, oldStop))  # start already discarded

# after
text = None
if oldStart >= tokens.GetBufferStartIndex():
    text = tokens.GetText(Interval(oldStart, oldStop))
Defensive patterns

Strategy: validation

Validate before calling

// C#: verify the interval fits the current window before GetText
int bStart = stream.GetBufferStartIndex();
int bStop = bStart + stream.TokenSource... /* use your accessor for tokens.Length */;
if (interval.a >= bStart && interval.b <= bStop) {
    text = stream.GetText(interval);
}

Try / catch

try { text = stream.GetText(interval); } catch (NotSupportedException) { // interval partially outside the rolling window: emit a placeholder (e.g., '<unavailable text>') or re-lex the source range }

Prevention

When it happens

Trigger: Calling GetText() for a range that starts before GetBufferStartIndex() (already-discarded tokens) or ends past the window; error handlers requesting the text of a wide context interval; calling GetText on an interval captured from an earlier rule that has since been consumed.

Common situations: Syntax-error listeners or custom visitors that build message text from GetText(Interval) while using an unbuffered stream for memory efficiency; long-running parses where requested intervals drift outside the window; default error listeners that print offending-token text.

Related errors


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