{"record":{"id":"e6c1c23a0843eddc","repo":"rust-lang/rust","slug":"cannot-parse-an-html-file-r","errorCode":null,"errorMessage":"Cannot parse an HTML file {!r}: {}","messagePattern":"Cannot parse an HTML file (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/etc/htmldocck.py","lineNumber":280,"sourceCode":"        with io.open(abspath, encoding=\"utf-8\") as f:\n            data = f.read()\n            self.files[path] = data\n            return data\n\n    def get_tree(self, path):\n        path = self.resolve_path(path)\n        if path in self.trees:\n            return self.trees[path]\n\n        abspath = self.get_absolute_path(path)\n        if not (os.path.exists(abspath) and os.path.isfile(abspath)):\n            raise FailedCheck(\"File does not exist {!r}\".format(path))\n\n        with io.open(abspath, encoding=\"utf-8\") as f:\n            try:\n                tree = ET.fromstringlist(f.readlines(), CustomHTMLParser())\n            except Exception as e:\n                raise RuntimeError(  # noqa: B904 FIXME: py2\n                    \"Cannot parse an HTML file {!r}: {}\".format(path, e)\n                )\n            self.trees[path] = tree\n            return self.trees[path]\n\n    def get_dir(self, path):\n        path = self.resolve_path(path)\n        abspath = self.get_absolute_path(path)\n        if not (os.path.exists(abspath) and os.path.isdir(abspath)):\n            raise FailedCheck(\"Directory does not exist {!r}\".format(path))\n\n\ndef check_string(data, pat, regexp):\n    pat = pat.replace(\"{{channel}}\", channel)\n    if not pat:\n        return True  # special case a presence testing\n    elif regexp:\n        return re.search(pat, data, flags=re.UNICODE) is not None","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/etc/htmldocck.py#L262-L298","documentation":"Raised as RuntimeError by CachedFiles.get_tree() when ET.fromstringlist() (using the CustomHTMLParser) fails to parse the file as HTML/XML. The custom parser is lenient about void elements and empty attributes but will still throw on malformed markup; the original parse exception is embedded in the message. Note the code suppresses the chain (FIXME: py2, should use 'raise ... from').","triggerScenarios":"A directive triggers get_tree() on a file that exists but whose content the parser cannot turn into an ElementTree: unclosed tags that aren't void elements, encoding issues, content that is not HTML at all, or an HTMLParser error during entity/charref handling.","commonSituations":"rustdoc regressed and emitted invalid HTML; the file is actually a redirect/placeholder (not real HTML); an entity reference in the document is not in name2codepoint; encoding mismatch (file declared utf-8 but contains invalid bytes).","solutions":["Open the referenced file and locate the malformed markup around the parser's reported offset.","If the HTML is genuinely broken, file a rustdoc bug and xfail/skip the test temporarily.","Ensure the file is actually HTML (not a 404 page or redirect) and is valid UTF-8.","If an entity is the culprit, confirm it is a named HTML entity the parser knows."],"exampleFix":"// before - rustdoc emitted an unbalanced tag\n<div class='item'><span>foo</div>\n\n// after - fix the source HTML so tags are properly closed\n<div class='item'><span>foo</span></div>","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\nfrom xml.etree import ElementTree as ET\n\ndef html_parses_cleanly(abspath) -> bool:\n    try:\n        with open(abspath, encoding=\"utf-8\") as f:\n            ET.fromstringlist(f.readlines(), CustomHTMLParser())\n        return True\n    except Exception as e:\n        return False\n\nif not html_parses_cleanly(os.path.join(doc_root, path)):\n    raise SystemExit(f\"htmldocck cannot parse {path!r} as HTML; inspect the file\")","typeGuard":"null","tryCatchPattern":"try:\n    tree = cache.get_tree(path)\nexcept RuntimeError as e:\n    if \"Cannot parse an HTML file\" in str(e):\n        logging.error(\"rustdoc produced unparseable HTML for %s; file a rustdoc bug\", path)\n    raise","preventionTips":["Treat invalid rustdoc HTML as a rustdoc regression, not a test-authoring issue.","Validate generated HTML parses before committing a directive that queries it.","Watch for encoding/entity errors when rustdoc emits unusual characters."],"tags":["htmldocck","rustdoc","html","parsing","xml"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}