antlr/antlr4 · error · ArgumentOutOfRangeException
start {start} or stop {stop} not in 0..{tokens.Count - 1}
Error message
start {start} or stop {stop} not in 0..{tokens.Count - 1} What it means
GetTokens(start, stop, types) filters tokens in the inclusive range start..stop and requires both endpoints to be within the currently buffered list (0 <= start, stop < tokens.Count). Out-of-range endpoints indicate the caller computed the range from stale or external positions. Note the quirk that start > stop returns null rather than throwing — only out-of-bounds bounds throw.
Source
Thrown at runtime/CSharp/src/BufferedTokenStream.cs:403
}
/// <summary>
/// Given a start and stop index, return a
/// <c>List</c>
/// of all tokens in
/// the token type
/// <c>BitSet</c>
/// . Return
/// <see langword="null"/>
/// if no tokens were found. This
/// method looks at both on and off channel tokens.
/// </summary>
public virtual IList<IToken> GetTokens(int start, int stop, BitSet types)
{
LazyInit();
if (start < 0 || stop >= tokens.Count || stop < 0 || start >= tokens.Count)
{
throw new ArgumentOutOfRangeException("start " + start + " or stop " + stop + " not in 0.." + (tokens.Count - 1));
}
if (start > stop)
{
return null;
}
// list = tokens[start:stop]:{T t, t.getType() in types}
IList<IToken> filteredTokens = new List<IToken>();
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (types == null || types.Get(t.Type))
{
filteredTokens.Add(t);
}
}
if (filteredTokens.Count == 0)
{
filteredTokens = null;View on GitHub (pinned to 7d5770395b)
Solutions
- Clamp both endpoints to [0, stream.Size - 1] before calling GetTokens
- Always derive start/stop from TokenIndex values of tokens obtained from the same stream instance
- Handle the null return for start > stop explicitly rather than expecting an empty list
Example fix
// before IList<IToken> ctx = stream.GetTokens(errOffendingToken.TokenIndex - 5, errOffendingToken.TokenIndex + 5, null); // throws near EOF // after int start = Math.Max(0, errToken.TokenIndex - 5); int stop = Math.Min(errToken.TokenIndex + 5, stream.Size - 1); IList<IToken> ctx = start <= stop ? stream.GetTokens(start, stop, null) : null;
Defensive patterns
Strategy: validation
Validate before calling
int start = Math.Max(0, requestedStart); int stop = Math.Min(requestedStop, stream.Size - 1); IList<IToken> tokens = start <= stop ? stream.GetTokens(start, stop, types) : null;
Prevention
- Compute token ranges only from TokenIndex values of tokens from the same stream
- Remember start > stop returns null rather than throwing — branch on it explicitly
When it happens
Trigger: Calling GetTokens with start or stop beyond the buffered tokens, e.g. stop taken from a token of a different (unbuffered or re-created) stream, negative indices, or calling before LazyInit/Size has fetched enough tokens (LazyInit runs first, but the buffer only extends to what has been consumed).
Common situations: Syntax-error highlighters asking for GetTokens(badToken.TokenIndex - 5, badToken.TokenIndex + 5) near the end of input; token-stream rewriting code that mixes indices from a before/after stream; IDE integrations computing ranges from editor positions instead of token indices.
Related errors
- token index {i} out of range 0..{tokens.Count - 1}
- {tokenIndex} not in 0..{tokens.Count - 1}
- tokenSource cannot be null
- cannot consume EOF
- get(${i}) outside buffer: ${bufferStartIndex}..${bufferStart
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/23fd314d5211e0f6.
Report an issue: GitHub.