antlr/antlr4 · error · IllegalArgumentException

at index isn't a valid rule name

Error message

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

What it means

For a lowercase reference in an XPath path, parser.getRuleIndex(word) returning -1 means no rule with that name exists in the grammar. IllegalArgumentException reports the word and its start index in the path string.

Solutions

  1. Verify the rule name against the grammar / generated parser: Arrays.asList(parser.getRuleNames()).contains(word)
  2. Ensure the parser instance passed to XPath is the same grammar that produced the tree
  3. Regenerate queries (or centralize them as constants) when rules are renamed

Example fix

// before
XPath.findAll(tree, "/statement/expression", parser);

// after
XPath.findAll(tree, "/statement/expr", parser); // rule is 'expr' in the grammar
Defensive patterns

Strategy: validation

Validate before calling

boolean knownRule = Arrays.asList(parser.getRuleNames()).contains(word);

Try / catch

try { XPath.findAll(tree, path, parser); } catch (IllegalArgumentException e) { /* message names the invalid rule and index; fix the name */ }

Prevention

When it happens

Trigger: XPath.findAll(tree, "/statement/expression", parser) when the grammar's rule is named expr, not expression.

Common situations: Rule renamed between grammar versions while XPath queries kept the old name; writing queries from the language spec instead of the actual grammar file; querying a tree produced by a different parser than the one passed in.

Related errors


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

Appendix: source

Thrown at runtime/Java/src/org/antlr/v4/runtime/tree/xpath/XPath.java:182

		switch ( wordToken.getType() ) {
			case XPathLexer.WILDCARD :
				return anywhere ?
					new XPathWildcardAnywhereElement() :
					new XPathWildcardElement();
			case XPathLexer.TOKEN_REF :
			case XPathLexer.STRING :
				if ( ttype==Token.INVALID_TYPE ) {
					throw new IllegalArgumentException(word+
													   " at index "+
													   wordToken.getStartIndex()+
													   " isn't a valid token name");
				}
				return anywhere ?
					new XPathTokenAnywhereElement(word, ttype) :
					new XPathTokenElement(word, ttype);
			default :
				if ( ruleIndex==-1 ) {
					throw new IllegalArgumentException(word+
													   " at index "+
													   wordToken.getStartIndex()+
													   " isn't a valid rule name");
				}
				return anywhere ?
					new XPathRuleAnywhereElement(word, ruleIndex) :
					new XPathRuleElement(word, ruleIndex);
		}
	}


	public static Collection<ParseTree> findAll(ParseTree tree, String xpath, Parser parser) {
		XPath p = new XPath(parser, xpath);
		return p.evaluate(tree);
	}

	/**
	 * Return a list of all nodes starting at {@code t} as root that satisfy the

View on GitHub (pinned to 7d5770395b)