rust-lang/rust · error · InvalidCheck

Non-absolute XPath is not supported due to implementation is

Error message

Non-absolute XPath is not supported due to implementation issues

What it means

Raised as InvalidCheck by normalize_xpath() when an XPath passed to a directive does not start with '//' or './/'. The htmldocck XPath matching is built on ElementTree.findall, which requires absolute (descendant-or-self) paths because there is no concept of a 'current node' relative path implemented. Relative or single-slash paths are rejected up front.

Source

Thrown at src/etc/htmldocck.py:223

def flatten(node):
    acc = []
    _flatten(node, acc)
    return "".join(acc)


def make_xml(text):
    xml = ET.XML("<xml>%s</xml>" % text)
    return xml


def normalize_xpath(path):
    path = path.replace("{{channel}}", channel)
    if path.startswith("//"):
        return "." + path  # avoid warnings
    elif path.startswith(".//"):
        return path
    else:
        raise InvalidCheck(
            "Non-absolute XPath is not supported due to implementation issues"
        )


class CachedFiles(object):
    def __init__(self, root):
        self.root = root
        self.files = {}
        self.trees = {}
        self.last_path = None

    def resolve_path(self, path):
        if path != "-":
            path = os.path.normpath(path)
            self.last_path = path
            return path
        elif self.last_path is None:
            raise InvalidCheck("Tried to use the previous path in the first command")

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Prefix the XPath with '//' to select descendants of the document root (e.g. `//div[@class='foo']`).
  2. If you need a path relative to a previously matched node, use './/' (also accepted).
  3. Avoid single leading '/' and bare tag names; they are not supported by this implementation.

Example fix

// before
//@ has: /html/body/div[@id='main'] 'text'

// after
//@ has: //body//div[@id='main'] 'text'
Defensive patterns

Strategy: validation

Validate before calling

def xpath_is_supported(path: str) -> bool:
    return path.startswith("//") or path.startswith(".//")

if not xpath_is_supported(xpath_from_directive):
    raise SystemExit(
        f"htmldocck only supports '//' or './/' XPaths; got {xpath_from_directive!r}."
    )

Type guard

def is_supported_xpath(path: str) -> bool:
    return path.startswith("//") or path.startswith(".//")

Try / catch

from srcetc_htmldocck import InvalidCheck
try:
    norm = normalize_xpath(path)
except InvalidCheck as e:
    if "Non-absolute XPath" in str(e):
        logging.error("rewrite the directive to use '//%s'", path.lstrip('/.'))
    raise

Prevention

When it happens

Trigger: Any directive that resolves an XPath (has/matches/count/snapshot with 3 args, etc.) passes the path through normalize_xpath; if the path is like '/html/body' or 'div' (no leading //), InvalidCheck is raised at htmldocck.py:223.

Common situations: Authoring a rustdoc test directive with a CSS-like or absolute-single-slash selector instead of the required '//' descendant axis; converting a CSS selector to XPath incorrectly.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/bc454cb8fdc2d127. Report an issue: GitHub.