{"record":{"id":"0fb1d564c21d7f0d","repo":"antlr/antlr4","slug":"interval-interval-not-in-token-buffer-window","errorCode":null,"errorMessage":"interval ${interval} not in token buffer window: ${bufferStartIndex}..${bufferStopIndex}","messagePattern":"interval (.+?) not in token buffer window: (.+?)\\.\\.(.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"runtime/CSharp/src/UnbufferedTokenStream.cs","lineNumber":387,"sourceCode":"\n        public virtual string SourceName\n        {\n            get\n            {\n                return TokenSource.SourceName;\n            }\n        }\n\n        [return: NotNull]\n        public virtual string GetText(Interval interval)\n        {\n            int bufferStartIndex = GetBufferStartIndex();\n            int bufferStopIndex = bufferStartIndex + tokens.Length - 1;\n            int start = interval.a;\n            int stop = interval.b;\n            if (start < bufferStartIndex || stop > bufferStopIndex)\n            {\n                throw new NotSupportedException(\"interval \" + interval + \" not in token buffer window: \" + bufferStartIndex + \"..\" + bufferStopIndex);\n            }\n            int a = start - bufferStartIndex;\n            int b = stop - bufferStartIndex;\n            StringBuilder buf = new StringBuilder();\n            for (int i = a; i <= b; i++)\n            {\n                IToken t = tokens[i];\n                buf.Append(t.Text);\n            }\n            return buf.ToString();\n        }\n\n        protected internal int GetBufferStartIndex()\n        {\n            return currentTokenIndex - p;\n        }\n    }\n}","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/CSharp/src/UnbufferedTokenStream.cs#L369-L405","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use CommonTokenStream when token text may be requested for arbitrary past intervals","Capture GetText for a rule's interval inside its exit listener/listener callback, while the tokens are guaranteed still inside the window","Before calling, verify interval.a >= GetBufferStartIndex() and interval.b <= bufferStartIndex + tokens.Length - 1, and skip or re-lex otherwise"],"exampleFix":"# before (Python-equivalent API usage pattern)\n# tokens = UnbufferedTokenStream(lexer); parser error listener calls:\ntext = tokens.GetText(Interval(oldStart, oldStop))  # start already discarded\n\n# after\ntext = None\nif oldStart >= tokens.GetBufferStartIndex():\n    text = tokens.GetText(Interval(oldStart, oldStop))","handlingStrategy":"validation","validationCode":"// C#: verify the interval fits the current window before GetText\nint bStart = stream.GetBufferStartIndex();\nint bStop = bStart + stream.TokenSource... /* use your accessor for tokens.Length */;\nif (interval.a >= bStart && interval.b <= bStop) {\n    text = stream.GetText(interval);\n}","typeGuard":null,"tryCatchPattern":"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 }","preventionTips":["Capture GetText for each rule inside its listener callback while tokens are still in the window","Switch to CommonTokenStream when text extraction for past intervals is required","Keep an open Mark() to widen the retained window during text-sensitive phases"],"tags":["antlr","csharp","token-stream","gettext","rolling-buffer"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}