{"record":{"id":"a995f7ddec37f673","repo":"antlr/antlr4","slug":"seek-to-index-outside-buffer-index-not-in-buff-a995f7","errorCode":null,"errorMessage":"seek to index outside buffer: {index} not in {bufferStartIndex}..{bufferStartIndex+n}","messagePattern":"seek to index outside buffer: (.+?) not in (.+?)\\.\\.(.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"runtime/Java/src/org/antlr/v4/runtime/UnbufferedTokenStream.java","lineNumber":259,"sourceCode":"\n\t@Override\n\tpublic void seek(int index) { // seek to absolute index\n\t\tif (index == currentTokenIndex) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (index > currentTokenIndex) {\n\t\t\tsync(index - currentTokenIndex);\n\t\t\tindex = Math.min(index, getBufferStartIndex() + n - 1);\n\t\t}\n\n\t\tint bufferStartIndex = getBufferStartIndex();\n\t\tint i = index - bufferStartIndex;\n\t\tif ( i < 0 ) {\n\t\t\tthrow new IllegalArgumentException(\"cannot seek to negative index \" + index);\n\t\t}\n\t\telse if (i >= n) {\n\t\t\tthrow new UnsupportedOperationException(\"seek to index outside buffer: \"+\n\t\t\t\t\t\t\t\t\t\t\t\t\tindex+\" not in \"+ bufferStartIndex +\"..\"+(bufferStartIndex +n));\n\t\t}\n\n\t\tp = i;\n\t\tcurrentTokenIndex = index;\n\t\tif (p == 0) {\n\t\t\tlastToken = lastTokenBufferStart;\n\t\t}\n\t\telse {\n\t\t\tlastToken = tokens[p-1];\n\t\t}\n\t}\n\n\t@Override\n\tpublic int size() {\n\t\tthrow new UnsupportedOperationException(\"Unbuffered stream cannot know its size\");\n\t}\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/UnbufferedTokenStream.java#L241-L277","documentation":"After syncing and clamping a forward seek, UnbufferedTokenStream verifies that the resulting relative position is still inside bufferStartIndex..bufferStartIndex+n. If it is not, the stream cannot honor the seek without retaining tokens, so it throws UnsupportedOperationException. In normal operation forward seeks are clamped to EOF, so this guard also catches inconsistent state or unsupported random access.","triggerScenarios":"Calling seek() with an absolute index that is not represented by the current buffer window after sync; using an UnbufferedTokenStream subclass or stream manipulation that leaves p/currentTokenIndex inconsistent; or generic code assuming every TokenStream supports arbitrary seeks.","commonSituations":"Generic IntStream utilities, custom lookahead/backtracking engines, and code migrated from BufferedTokenStream. It commonly indicates the chosen stream implementation does not provide the required access model rather than a grammar bug.","solutions":["Use BufferedTokenStream or CommonTokenStream for random-access seeks.","Keep a marker active for the whole region in which seeks are allowed on an unbuffered stream.","Seek only to indexes already represented in the buffer and never after release of the protecting mark.","If subclassing UnbufferedTokenStream, preserve its p, n, and currentTokenIndex invariants."],"exampleFix":"// before\nUnbufferedTokenStream<Token> tokens = new UnbufferedTokenStream<>(lexer);\ntokens.seek(requestedTokenIndex); // may fall outside retained window\n\n// after\nCommonTokenStream tokens = new CommonTokenStream(lexer);\ntokens.seek(requestedTokenIndex); // buffered until EOF","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"static boolean supportsRandomAccess(TokenStream tokens) {\n    return tokens instanceof BufferedTokenStream;\n}","tryCatchPattern":"try {\n    tokens.seek(index);\n} catch (UnsupportedOperationException e) {\n    throw new IllegalArgumentException(\"Random access required; use BufferedTokenStream\", e);\n}","preventionTips":["Choose the token-stream implementation based on required access pattern.","Keep marked regions open during all seeks.","Do not assume IntStream.seek is random-access for every implementation."],"tags":["antlr","java","token-stream","seek","random-access"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}