antlr/antlr4 · error · ArgumentException

${word} at index ${startIndex} isn't a valid rule name

Error message

${word} at index ${startIndex} isn't a valid rule name

What it means

A word starting with a lowercase character is lexed as a RuleRef. The runtime asks the supplied Parser for its rule index; -1 means no rule with that name exists. The word is therefore a syntactically valid rule reference but is not defined by the target grammar.

Source

Thrown at runtime/CSharp/src/Tree/Xpath/XPath.cs:230

                {
                    return anywhere ? new XPathWildcardAnywhereElement() : (XPathElement)new XPathWildcardElement();
                }

                case XPathLexer.TokenRef:
                case XPathLexer.String:
                {
                    if (ttype == TokenConstants.InvalidType)
                    {
                        throw new ArgumentException(word + " at index " + wordToken.StartIndex + " isn't a valid token name");
                    }
                    return anywhere ? new XPathTokenAnywhereElement(word, ttype) : (XPathElement)new XPathTokenElement(word, ttype);
                }

                default:
                {
                    if (ruleIndex == -1)
                    {
                        throw new ArgumentException(word + " at index " + wordToken.StartIndex + " isn't a valid rule name");
                    }
                    return anywhere ? new XPathRuleAnywhereElement(word, ruleIndex) : (XPathElement)new XPathRuleElement(word, ruleIndex);
                }
            }
        }

        public static ICollection<IParseTree> FindAll(IParseTree tree, string xpath, Parser parser)
        {
            Antlr4.Runtime.Tree.Xpath.XPath p = new Antlr4.Runtime.Tree.Xpath.XPath(parser, xpath);
            return p.Evaluate(tree);
        }

        /// <summary>
        /// Return a list of all nodes starting at
        /// <paramref name="t"/>
        /// as root that satisfy the
        /// path. The root
        /// <c>/</c>

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Check parser.RuleNames and use the exact rule name from the generated parser.
  2. If the name is a token, make its first character uppercase so it is treated as a TokenRef.
  3. Regenerate the parser and lexer from the current grammar.
  4. Verify parser.GetRuleIndex(word) is not -1 before constructing XPath.

Example fix

// before
var xpath = new Antlr4.Runtime.Tree.Xpath.XPath(parser, "/expression");

// after
var xpath = new Antlr4.Runtime.Tree.Xpath.XPath(parser, "/expr"); // exact generated rule name
Defensive patterns

Strategy: validation

Validate before calling

static bool IsKnownRuleName(Parser parser, string word) {
    return char.IsLower(word[0]) && parser.GetRuleIndex(word) != -1;
}

Try / catch

try { var p = new Antlr4.Runtime.Tree.Xpath.XPath(parser, xpath); }
catch (ArgumentException ex) when (ex.Message.EndsWith("isn't a valid rule name")) { /* report unknown rule and check parser.RuleNames */ }

Prevention

When it happens

Trigger: Calling XPath with "/expr" when the grammar has no expr rule; using a renamed or removed rule; passing a parser generated from different grammar sources; or lowercasing a token name so it is interpreted as a rule.

Common situations: Grammar refactoring changes rule names; stale generated parser files; examples copied from another grammar; or uncertainty about whether a vocabulary name is a token or a rule.

Related errors


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