antlr/antlr4 · error · Exception
%s at index %d isn't a valid rule name
Error message
%s at index %d isn't a valid rule name
What it means
Raised by XPath.getXPathElement() in the Python3 runtime when a RULE_REF in the path does not name any parser rule. The evaluator needs the rule index to match rule-invocation nodes; parser.ruleNames.index() returns -1 for unknown names.
Source
Thrown at runtime/Python3/src/antlr4/xpath/XPath.py:160
tsource = self.parser.getTokenStream().tokenSource
ttype = Token.INVALID_TYPE
if wordToken.type == XPathLexer.TOKEN_REF:
if word in tsource.ruleNames:
ttype = tsource.ruleNames.index(word) + 1
else:
if word in tsource.literalNames:
ttype = tsource.literalNames.index(word)
if ttype == Token.INVALID_TYPE:
raise Exception("%s at index %d isn't a valid token name" % (word, wordToken.tokenIndex))
return XPathTokenAnywhereElement(word, ttype) if anywhere else XPathTokenElement(word, ttype)
else:
ruleIndex = self.parser.ruleNames.index(word) if word in self.parser.ruleNames else -1
if ruleIndex == -1:
raise Exception("%s at index %d isn't a valid rule name" % (word, wordToken.tokenIndex))
return XPathRuleAnywhereElement(word, ruleIndex) if anywhere else XPathRuleElement(word, ruleIndex)
@staticmethod
def findAll(tree:ParseTree, xpath:str, parser:Parser):
p = XPath(parser, xpath)
return p.evaluate(tree)
#
# Return a list of all nodes starting at {@code t} as root that satisfy the
# path. The root {@code /} is relative to the node passed to
# {@link #evaluate}.
#
def evaluate(self, t:ParseTree):
dummyRoot = ParserRuleContext()
dummyRoot.children = [t] # don't set t's parent.
work = [dummyRoot]View on GitHub (pinned to 7d5770395b)
Solutions
- Match the rule name exactly to an entry in parser.ruleNames
- If the name is a token/lexer rule, reference it as a token instead
- Update XPath strings after every grammar rename and regenerate
Example fix
# before: rule is 'expression' in this grammar nodes = XPath.findAll(tree, "/expr", parser) # after nodes = XPath.findAll(tree, "/expression", parser)
Defensive patterns
Strategy: validation
Validate before calling
if rule_name not in parser.ruleNames:
raise ValueError(f'{rule_name} is not a parser rule name') Type guard
def is_known_rule_name(name: str, parser) -> bool:
return name in parser.ruleNames Try / catch
try:
nodes = XPath.findAll(tree, xpath, parser)
except Exception as e:
if "isn't a valid rule name" in str(e):
# find the correct rule name in parser.ruleNames
... Prevention
- Cross-check rule names with parser.ruleNames
- Regenerate code and XPath queries together after grammar edits
When it happens
Trigger: XPath with a path like '/expr' when the parser has no rule named expr (e.g. it was renamed to expression), or using a lexer rule name in rule position.
Common situations: Grammar refactors, copy/pasting XPath examples from another grammar, or confusion between lexer and parser rule namespaces.
Related errors
- Missing element after %s
- Unknown path element %s
- Missing path element at end of path
- %s at index %d isn't a valid token name
- The current recognizer does not provide a list of token name
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/3c6dcf464e024fa5.
Report an issue: GitHub.