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

  1. Validate 0 <= stateNumber < atn.states.Count before calling
  2. Regenerate parsers with the same ANTLR version as the runtime package and clean bin/obj
  3. 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

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


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/31704a5735673615. Report an issue: GitHub.