antlr/antlr4 · error · Exception

Missing element after %s

Error message

Missing element after %s

What it means

Raised by XPath element parsing in the Python3 runtime when a '/' or '//' root/anywhere token is the last token in the path, so no element follows it. A separator must be followed by a rule name, token name, wildcard, or string.

Source

Thrown at runtime/Python3/src/antlr4/xpath/XPath.py:106

        tokenStream = CommonTokenStream(lexer)
        try:
            tokenStream.fill()
        except LexerNoViableAltException as e:
            pos = lexer.column
            msg = "Invalid tokens or characters at index %d in path '%s'" % (pos, path)
            raise Exception(msg, e)

        tokens = iter(tokenStream.tokens)
        elements = list()
        for el in tokens:
            invert = False
            anywhere = False
            # Check for path separators, if none assume root
            if el.type in [XPathLexer.ROOT, XPathLexer.ANYWHERE]:
                anywhere = el.type == XPathLexer.ANYWHERE
                next_el = next(tokens, None)
                if not next_el:
                    raise Exception('Missing element after %s' % el.getText())
                else:
                    el = next_el
            # Check for bangs
            if el.type == XPathLexer.BANG:
                invert = True
                next_el = next(tokens, None)
                if not next_el:
                    raise Exception('Missing element after %s' % el.getText())
                else:
                    el = next_el
            # Add searched element
            if el.type in [XPathLexer.TOKEN_REF, XPathLexer.RULE_REF, XPathLexer.WILDCARD, XPathLexer.STRING]:
                element = self.getXPathElement(el, anywhere)
                element.invert = invert
                elements.append(element)
            elif el.type==Token.EOF:
                break
            else:

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Remove the trailing '/' or '//' from the path
  2. Follow every separator with a concrete element (rule name, token name, '*', or quoted string)
  3. Strip trailing separators when constructing paths dynamically: path.rstrip('/')

Example fix

# before
nodes = XPath.findAll(tree, "//expr//", parser)

# after
nodes = XPath.findAll(tree, "//expr", parser)
Defensive patterns

Strategy: validation

Validate before calling

if xpath.rstrip() != xpath.rstrip('/'):
    raise ValueError('XPath must not end with a separator')

Try / catch

try:
    nodes = XPath.findAll(tree, xpath, parser)
except Exception as e:
    if str(e).startswith('Missing element after'):
        xpath = xpath.rstrip('/\\')  # retry once with trimmed path
        nodes = XPath.findAll(tree, xpath, parser)

Prevention

When it happens

Trigger: Calling XPath(parser, '/expr/') or XPath(parser, '//') — the trailing separator has no following element.

Common situations: Trailing slash habit from filesystem paths, or building paths by joining components with '/' and accidentally leaving a trailing separator.

Related errors


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