{"record":{"id":"c8b9ecfacfa04391","repo":"antlr/antlr4","slug":"interval-interval-outside-buffer-bufferstartin","errorCode":null,"errorMessage":"interval {interval} outside buffer: {bufferStartIndex}..{bufferStartIndex+n-1}","messagePattern":"interval (.+?) outside buffer: (.+?)\\.\\.(.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java","lineNumber":336,"sourceCode":"\n\t\treturn name;\n\t}\n\n\t@Override\n\tpublic String getText(Interval interval) {\n\t\tif (interval.a < 0 || interval.b < interval.a - 1) {\n\t\t\tthrow new IllegalArgumentException(\"invalid interval\");\n\t\t}\n\n\t\tint bufferStartIndex = getBufferStartIndex();\n\t\tif (n > 0 && data[n - 1] == Character.MAX_VALUE) {\n\t\t\tif (interval.a + interval.length() > bufferStartIndex + n) {\n\t\t\t\tthrow new IllegalArgumentException(\"the interval extends past the end of the stream\");\n\t\t\t}\n\t\t}\n\n\t\tif (interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n) {\n\t\t\tthrow new UnsupportedOperationException(\"interval \"+interval+\" outside buffer: \"+\n\t\t\t                    bufferStartIndex+\"..\"+(bufferStartIndex+n-1));\n\t\t}\n\t\t// convert from absolute to local index\n\t\tint i = interval.a - bufferStartIndex;\n\t\treturn new String(data, i, interval.length());\n\t}\n\n\tprotected final int getBufferStartIndex() {\n\t\treturn currentCharIndex - p;\n\t}\n}\n","sourceCodeStart":318,"sourceCodeEnd":348,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java#L318-L348","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nparser.buildParseTree = true;\nnew ParseTreeWalker().walk(listener, tree);\n// listener later calls ctx.getText() -> chars already discarded -> throws\n\n// after\n// extract needed text during the parse:\nclass MyListener extends MyParserBaseListener {\n    @Override public void exitEveryRule(ParserRuleContext ctx) {\n        record(ctx, tokens.getText(ctx)); // while window still covers ctx\n    }\n}","handlingStrategy":"validation","validationCode":"int bufferStart = /* track via marks, or compute as index() - p equivalent */ floorIndex;\nif (interval.a < floorIndex) {\n    text = previouslyExtracted.get(interval); // cache text eagerly during parse\n} else {\n    text = stream.getText(interval);\n}","typeGuard":null,"tryCatchPattern":"try { stream.getText(interval); }\ncatch (UnsupportedOperationException e) { /* fall back to cached text captured during the parse */ }","preventionTips":["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"],"tags":["antlr","char-stream","interval","buffer","gettext"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}