{"record":{"id":"722d7e31c3244100","repo":"searxng/searxng","slug":"searxenginexpathexception","errorCode":null,"errorMessage":"SearxEngineXPathException","messagePattern":"SearxEngineXPathException","errorType":"exception","errorClass":"SearxEngineXPathException","httpStatus":null,"severity":"error","filePath":"searx/utils.py","lineNumber":555,"sourceCode":"\n    ``TypeError``:\n      Raised when ``xpath_spec`` is neither a :py:obj:`str` nor a\n      :py:obj:`lxml.etree.XPath`.\n\n    ``SearxXPathSyntaxException``:\n      Raised when there is a syntax error in the *XPath* selector (``str``).\n\n    ``SearxEngineXPathException:``\n      Raised when the XPath can't be evaluated (masked\n      :py:obj:`lxml.etree..XPathError`).\n    \"\"\"\n    xpath: XPath = get_xpath(xpath_spec)\n    try:\n        # https://lxml.de/xpathxslt.html#xpath-return-values\n        return xpath(element)\n    except XPathError as e:\n        arg = ' '.join([str(i) for i in e.args])\n        raise SearxEngineXPathException(xpath_spec, arg) from e\n\n\ndef eval_xpath_list(element: ElementType, xpath_spec: XPathSpecType, min_len: int | None = None) -> list[t.Any]:\n    \"\"\"Same as :py:obj:`searx.utils.eval_xpath`, but additionally ensures the\n    return value is a :py:obj:`list`.  The minimum length of the list is also\n    checked (if ``min_len`` is set).\"\"\"\n\n    result: list[t.Any] = eval_xpath(element, xpath_spec)\n    if not isinstance(result, list):\n        raise SearxEngineXPathException(xpath_spec, 'the result is not a list')\n    if min_len is not None and min_len > len(result):\n        raise SearxEngineXPathException(xpath_spec, 'len(xpath_str) < ' + str(min_len))\n    return result\n\n\ndef eval_xpath_getindex(\n    element: ElementType,\n    xpath_spec: XPathSpecType,","sourceCodeStart":537,"sourceCodeEnd":573,"githubUrl":"https://github.com/searxng/searxng/blob/9fea41204fdfa7a5cfa15b0ebd12904c520478ce/searx/utils.py#L537-L573","documentation":"SearxEngineXPathException raised by eval_xpath when evaluating an already-compiled XPath against an element raises lxml XPathError — typically because the expression is evaluated on the wrong node type (e.g. an attribute node) or lxml runtime limits are hit, not a syntax error.","triggerScenarios":"Calling eval_xpath(element, xpath) where xpath(element) raises XPathError, e.g. expressions expecting element context applied to attribute/text nodes, or very unusual evaluation failures inside lxml.","commonSituations":"Engine code evaluating element-relative paths on nodes obtained from attribute selection, or lxml version changes altering evaluation behavior on certain node types.","solutions":["Evaluate on element nodes: select '//a/@href' text separately but path expressions on elements","Re-check the expression with SearxXPathSyntaxException causes ruled out — test directly: element.xpath(expr)","Pin/upgrade lxml to a version compatible with your SearXNG release"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    res = eval_xpath(dom, xp)\nexcept SearxEngineXPathException as e:\n    logger.warning('xpath eval failed for %s: %s', xp, e)\n    res = None","preventionTips":["Evaluate path expressions against element nodes, not attribute/text nodes","Test engines against saved HTML fixtures in CI"],"tags":["searxng","xpath","engine","lxml"],"backgroundTag":"xpath-evaluation-error","analyzedSha":"9fea41204fdfa7a5cfa15b0ebd12904c520478ce","analyzedAt":"2026-08-27T06:40:00.395Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}