{"record":{"id":"0185620c917402af","repo":"antlr/antlr4","slug":"missing-path-element-at-end-of-path-018562","errorCode":null,"errorMessage":"Missing path element at end of path","messagePattern":"Missing path element at end of path","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"runtime/Python3/src/antlr4/xpath/XPath.py","lineNumber":135,"sourceCode":"            # Add searched element\n            if el.type in [XPathLexer.TOKEN_REF, XPathLexer.RULE_REF, XPathLexer.WILDCARD, XPathLexer.STRING]:\n                element = self.getXPathElement(el, anywhere)\n                element.invert = invert\n                elements.append(element)\n            elif el.type==Token.EOF:\n                break\n            else:\n                raise Exception(\"Unknown path element %s\" % lexer.symbolicNames[el.type])\n        return elements\n\n    #\n    # Convert word like {@code#} or {@code ID} or {@code expr} to a path\n    # element. {@code anywhere} is {@code true} if {@code //} precedes the\n    # word.\n    #\n    def getXPathElement(self, wordToken:Token, anywhere:bool):\n        if wordToken.type==Token.EOF:\n            raise Exception(\"Missing path element at end of path\")\n\n        word = wordToken.text\n        if wordToken.type==XPathLexer.WILDCARD :\n            return XPathWildcardAnywhereElement() if anywhere else XPathWildcardElement()\n\n        elif wordToken.type in [XPathLexer.TOKEN_REF, XPathLexer.STRING]:\n            tsource = self.parser.getTokenStream().tokenSource\n\n            ttype = Token.INVALID_TYPE\n            if wordToken.type == XPathLexer.TOKEN_REF:\n                if word in tsource.ruleNames:\n                    ttype = tsource.ruleNames.index(word) + 1\n            else:\n                if word in tsource.literalNames:\n                    ttype = tsource.literalNames.index(word)\n\n            if ttype == Token.INVALID_TYPE:\n                raise Exception(\"%s at index %d isn't a valid token name\" % (word, wordToken.tokenIndex))","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Python3/src/antlr4/xpath/XPath.py#L117-L153","documentation":"Raised by XPath.getXPathElement() in the Python3 runtime when the element token is EOF, i.e. the path ends where an element (rule name, token name, wildcard, or string) is required. It is the internal counterpart of the 'Missing element after' checks.","triggerScenarios":"A path whose last meaningful token is a separator or '!', so the element slot receives EOF; commonly reached through getXPathElement directly or edge cases in splitToTokens.","commonSituations":"Paths ending in '/', '//', or '!', especially dynamically assembled ones.","solutions":["Terminate the path with a concrete element instead of a separator or bang","Validate assembled paths end with an identifier, '*', or quoted string","Strip trailing separator/bang characters before evaluation"],"exampleFix":"# before\nnodes = XPath.findAll(tree, \"//expr/\", parser)\n\n# after\nnodes = XPath.findAll(tree, \"//expr\", parser)","handlingStrategy":"validation","validationCode":"import re\nif not re.search(r\"([A-Za-z_][A-Za-z0-9_]*|\\*|'[^']*')\\s*$\", xpath.rstrip()):\n    raise ValueError('XPath must end with an element')","typeGuard":null,"tryCatchPattern":"try:\n    nodes = XPath.findAll(tree, xpath, parser)\nexcept Exception as e:\n    if 'Missing path element' in str(e):\n        # fix trailing separator/bang\n        ...","preventionTips":["End every XPath with an identifier, '*', or quoted string","Validate generated paths before evaluation"],"tags":["antlr","python","xpath","validation"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}