antlr/antlr4 · error · ArgumentException
Invalid state number.
Error message
Invalid state number.
What it means
ATN.GetExpectedTokens(stateNumber, context) computes the set of tokens acceptable in a given ATN state. It throws ArgumentException when stateNumber is outside [0, states.Count), because there is no such state to consult. State numbers come from ATNState.stateNumber assigned during ATN construction/deserialization.
Source
Thrown at runtime/CSharp/src/Atn/ATN.cs:234
/// .</p>
/// </summary>
/// <param name="stateNumber">the ATN state number</param>
/// <param name="context">the full parse context</param>
/// <returns>
/// The set of potentially valid input symbols which could follow the
/// specified state in the specified context.
/// </returns>
/// <exception cref="System.ArgumentException">
/// if the ATN does not contain a state with
/// number
/// <paramref name="stateNumber"/>
/// </exception>
[return: NotNull]
public virtual IntervalSet GetExpectedTokens(int stateNumber, RuleContext context)
{
if (stateNumber < 0 || stateNumber >= states.Count)
{
throw new ArgumentException("Invalid state number.");
}
RuleContext ctx = context;
ATNState s = states[stateNumber];
IntervalSet following = NextTokens(s);
if (!following.Contains(TokenConstants.EPSILON))
{
return following;
}
IntervalSet expected = new IntervalSet();
expected.AddAll(following);
expected.Remove(TokenConstants.EPSILON);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
{
ATNState invokingState = states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
following = NextTokens(rt.followState);
expected.AddAll(following);
expected.Remove(TokenConstants.EPSILON);View on GitHub (pinned to 7d5770395b)
Solutions
- Validate 0 <= stateNumber < atn.states.Count before calling
- Regenerate parsers with the same ANTLR version as the runtime package and clean bin/obj
- If it surfaces from deep inside the runtime, check for mismatched Antlr4.Runtime versions across projects in the solution
Example fix
// before
var expected = atn.GetExpectedTokens(stateNumber, ctx);
// after
var expected = (stateNumber >= 0 && stateNumber < atn.states.Count)
? atn.GetExpectedTokens(stateNumber, ctx)
: new IntervalSet(); Defensive patterns
Strategy: validation
Validate before calling
bool valid = stateNumber >= 0 && stateNumber < atn.states.Count;
Type guard
static bool IsValidStateNumber(ATN atn, int n) => n >= 0 && n < atn.states.Count;
Try / catch
try { atn.GetExpectedTokens(n, ctx); } catch (ArgumentException) { /* state number out of range; re-sync parser/ATN */ } Prevention
- Never hand-pick ATN state numbers; carry them from ATNState.stateNumber
- Regenerate parsers and clean bin/obj after runtime upgrades
When it happens
Trigger: Calling atn.GetExpectedTokens(n, ctx) with n < 0 or n >= atn.states.Count; commonly indirectly via Parser.GetExpectedTokens / error listeners when a DFA/ATN cache or serialized ATN is inconsistent with the runtime version.
Common situations: Mixing a C# runtime version with serialized ATN data or generated code from a different version, hand-manipulating ATN state numbers, or stale generated parsers after upgrading the runtime NuGet package.
Related errors
- The ATN must be a lexer ATN.
- Invalid state number.
- Serialized ATN data element[i] = v doesn't fit in 31 bits
- The object is read only.
- Couldn't identify final state of the precedence rule prefix
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/31704a5735673615.
Report an issue: GitHub.