{"record":{"id":"9367b126d4cc35ce","repo":"python/cpython","slug":"unknown-declaration-r-in-internal-subset","errorCode":null,"errorMessage":"unknown declaration %r in internal subset","messagePattern":"unknown declaration %r in internal subset","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Lib/_markupbase.py","lineNumber":211,"sourceCode":"                        \"unexpected char in internal subset (in %r)\" % s\n                    )\n                if (j + 2) == n:\n                    # end of buffer; incomplete\n                    return -1\n                if (j + 4) > n:\n                    # end of buffer; incomplete\n                    return -1\n                if rawdata[j:j+4] == \"<!--\":\n                    j = self.parse_comment(j, report=0)\n                    if j < 0:\n                        return j\n                    continue\n                name, j = self._scan_name(j + 2, declstartpos)\n                if j == -1:\n                    return -1\n                if name not in {\"attlist\", \"element\", \"entity\", \"notation\"}:\n                    self.updatepos(declstartpos, j + 2)\n                    raise AssertionError(\n                        \"unknown declaration %r in internal subset\" % name\n                    )\n                # handle the individual names\n                meth = getattr(self, \"_parse_doctype_\" + name)\n                j = meth(j, declstartpos)\n                if j < 0:\n                    return j\n            elif c == \"%\":\n                # parameter entity reference\n                if (j + 1) == n:\n                    # end of buffer; incomplete\n                    return -1\n                s, j = self._scan_name(j + 1, declstartpos)\n                if j < 0:\n                    return j\n                if rawdata[j] == \";\":\n                    j = j + 1\n            elif c == \"]\":","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_markupbase.py#L193-L229","documentation":"AssertionError raised by _markupbase.ParserBase._parse_doctype_subset when a markup declaration inside a DOCTYPE internal subset has a name other than attlist, element, entity, or notation. XML/SHTML restrict internal-subset declarations to those four (plus comments and PE references); the stdlib scanner enforces this and rejects anything else, echoing the scanned name.","triggerScenarios":"HTMLParser.feed() on <!DOCTYPE d [ <!INCLUDE[ ... ]> ]> or <!DOCTYPE d [ <!ATTLIST2 ...> ]> — any '<!name' in the subset whose name is not in {attlist, element, entity, notation} (note: names are lowercased by _scan_name).","commonSituations":"Nested marked sections or conditional blocks misplaced inside the DOCTYPE subset; typos in DTD keywords; copying SGML constructs (e.g. <!SHORTREF>) into HTML doctypes; generated documents gluing fragments together.","solutions":["Move constructs like <![...[ ]]> sections out of the internal subset or remove them.","Correct the declaration keyword to ELEMENT/ATTLIST/ENTITY/NOTATION as intended.","Strip the whole internal subset (regex the '[...]' portion of the DOCTYPE) if it is not needed for parsing.","Catch AssertionError and skip to the matching '>' of the offending declaration, then continue feed()."],"exampleFix":"# before\nHTMLParser().feed('<!DOCTYPE d [ <!ELEMENT2 a EMPTY > ]>')  # AssertionError: unknown declaration\n\n# after\nHTMLParser().feed('<!DOCTYPE d [ <!ELEMENT a EMPTY > ]>')\n# or: HTMLParser().feed(re.sub(r'<!DOCTYPE\\s+\\w+\\s*\\[.*?\\]', '<!DOCTYPE d>', raw, flags=re.S))","handlingStrategy":"try-catch","validationCode":"import re\n_OK_NAMES = {'attlist', 'element', 'entity', 'notation'}\n\ndef subset_decls_ok(raw: str) -> bool:\n    m = re.search(r'<!DOCTYPE[^\\[]*\\[([^\\]]*)\\]', raw, re.I | re.S)\n    if not m:\n        return True\n    return all((n or '').lower() in _OK_NAMES\n               for n in re.findall(r'<!(\\w+)', m.group(1)))","typeGuard":null,"tryCatchPattern":"try:\n    parser.feed(data)\nexcept AssertionError as e:\n    if 'unknown declaration' in str(e):\n        pos = data.find('<!', data.lower().find('<!doctype'))\n        end = data.find('>', pos)\n        data = data[:pos] + data[end + 1:]\n        parser.reset(); parser.feed(data)\n    else:\n        raise","preventionTips":["Restrict internal subsets to ELEMENT/ATTLIST/ENTITY/NOTATION.","Never nest marked sections inside a DOCTYPE subset.","Strip or validate DTD snippets coming from third-party feeds."],"tags":["markup","html-parser","dtd","doctype","parsing"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}