antlr/antlr4 · error · ArgumentException
cannot seek to negative index ${index}
Error message
cannot seek to negative index ${index} What it means
UnbufferedCharStream keeps only a rolling window of already unread data. Seek() maps the requested absolute index to a buffer offset; a negative offset means the position was discarded and cannot be restored. Backward seeks are therefore illegal once the needed data has left the buffer.
Source
Thrown at runtime/CSharp/src/UnbufferedCharStream.cs:385
/// <c>index-bufferStartIndex</c>
/// .
/// </remarks>
public virtual void Seek(int index)
{
if (index == currentCharIndex)
{
return;
}
if (index > currentCharIndex)
{
Sync(index - currentCharIndex);
index = Math.Min(index, BufferStartIndex + n - 1);
}
// index == to bufferStartIndex should set p to 0
int i = index - BufferStartIndex;
if (i < 0)
{
throw new ArgumentException("cannot seek to negative index " + index);
}
else
{
if (i >= n)
{
throw new NotSupportedException("seek to index outside buffer: " + index + " not in " + BufferStartIndex + ".." + (BufferStartIndex + n));
}
}
p = i;
currentCharIndex = index;
if (p == 0)
{
lastChar = lastCharBufferStart;
}
else
{
lastChar = data[p - 1];
}View on GitHub (pinned to 7d5770395b)
Solutions
- Do not seek backward on UnbufferedCharStream; process input in one forward pass.
- Keep a Mark() active for any earlier position that must remain seekable and release it only after seeking is complete.
- Use AntlrInputStream (fully buffered characters) when backward seeks are required.
Example fix
// before var chars = new UnbufferedCharStream(reader, 4096); chars.Seek(0); // after var chars = new AntlrInputStream(reader); // supports random access chars.Seek(0);
Defensive patterns
Strategy: validation
Validate before calling
if (targetIndex < chars.Index && randomAccessRequired)
chars = new AntlrInputStream(reader); // or retain a Mark() Type guard
static bool SupportsBackwardSeek(ICharStream stream) => stream is not UnbufferedCharStream;
Try / catch
try { chars.Seek(index); }
catch (ArgumentException ex) when (ex.Message.StartsWith("cannot seek to negative index")) { /* use buffered stream or keep markers */ } Prevention
- Treat UnbufferedCharStream as forward-only unless markers protect old data.
- Use AntlrInputStream for backtracking/reset workloads.
- Keep Mark() active across any backward seeks.
When it happens
Trigger: Calling Seek(oldIndex) after consuming beyond the retained window; releasing the marker that protected old data and then seeking back; or custom code assuming ICharStream supports arbitrary random access.
Common situations: Backtracking or reset logic is used with an unbuffered stream; a parser strategy requires rewinding; or migration from AntlrInputStream/CommonTokenStream to UnbufferedCharStream without preserving markers.
Related errors
- seek to index outside buffer: ${index} not in ${bufferStartI
- cannot consume EOF
- release() called with an invalid marker.
- Unbuffered stream cannot know its size
- interval ${interval} outside buffer: ${bufferStartIndex}..${
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/ec754a17802d6c10.
Report an issue: GitHub.