{"record":{"id":"c80023c8a7ddaac4","repo":"antlr/antlr4","slug":"seek-to-index-outside-buffer-index-not-in-buff","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/UnbufferedCharStream.java","lineNumber":294,"sourceCode":"\t */\n    @Override\n    public void seek(int index) {\n\t\tif (index == currentCharIndex) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (index > currentCharIndex) {\n\t\t\tsync(index - currentCharIndex);\n\t\t\tindex = Math.min(index, getBufferStartIndex() + n - 1);\n\t\t}\n\n        // index == to bufferStartIndex should set p to 0\n        int i = index - getBufferStartIndex();\n        if ( i < 0 ) {\n\t\t\tthrow new IllegalArgumentException(\"cannot seek to negative index \" + index);\n\t\t}\n\t\telse if (i >= n) {\n            throw new UnsupportedOperationException(\"seek to index outside buffer: \"+\n                    index+\" not in \"+getBufferStartIndex()+\"..\"+(getBufferStartIndex()+n));\n        }\n\n\t\tp = i;\n\t\tcurrentCharIndex = index;\n\t\tif (p == 0) {\n\t\t\tlastChar = lastCharBufferStart;\n\t\t}\n\t\telse {\n\t\t\tlastChar = data[p-1];\n\t\t}\n    }\n\n    @Override\n    public int size() {\n        throw new UnsupportedOperationException(\"Unbuffered stream cannot know its size\");\n    }\n","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java#L276-L312","documentation":"UnbufferedCharStream.seek(index) throws UnsupportedOperationException when the computed offset lands at or beyond the number of buffered characters (i >= n). Forward seeks sync() first and clamp to the last available index, so this fires mainly on backward seeks whose target is inside the window arithmetic but outside the actual data, or on defensive edge cases when the buffer cannot satisfy the request (e.g., seeking far past EOF with an exhausted source).","triggerScenarios":"seek(target) where target exceeds the end of the stream after sync has buffered EOF; seeking while the buffer is empty or was reset concurrently; index arithmetic that skips the early-return and clamp paths.","commonSituations":"Calling seek with a user-supplied offset that assumes the input is longer than it is; progress reporting code seeking to percentage positions in the stream.","solutions":["Clamp the target to the last valid index before seeking: index = Math.min(index, lastIndexKnown)","Verify the target is within the marked/retained window and at or before EOF before calling seek","Use a buffered stream if you need position-jump semantics on the whole input"],"exampleFix":"// before\nstream.seek(requestedOffset); // may land past buffered data / EOF\n\n// after\nint last = stream.getBufferStartIndex() + /* buffered count via LA probing */ 0;\n// safer: only seek within a held mark's window\nint m = stream.mark();\ntry {\n    int target = Math.min(requestedOffset, stream.index());\n    stream.seek(target);\n} finally { stream.release(m); }","handlingStrategy":"validation","validationCode":"int target = Math.min(requestedIndex, lastKnownIndex); // clamp to at-or-before EOF\nif (target < stream.index()) {\n    // backward seek: ensure within the retained window (see error 52 guard)\n}\nstream.seek(target);","typeGuard":null,"tryCatchPattern":"try { stream.seek(target); }\ncatch (UnsupportedOperationException e) { /* clamp target into the buffer window and retry once */ }","preventionTips":["Clamp seek targets to known-valid indexes before calling","Validate user-supplied offsets against input length before seeking","Prefer relative consumption over absolute seeks on unbuffered streams"],"tags":["antlr","char-stream","seek","eof","buffer"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}