{"record":{"id":"2acbe30df336930b","repo":"swc-project/swc","slug":"stray-doctype","errorCode":null,"errorMessage":"Stray doctype","messagePattern":"Stray doctype","errorType":"exception","errorClass":"swc_html_parser::error::Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":712,"sourceCode":"            // Insert the token's character.\n            //\n            // Set the frameset-ok flag to \"not ok\".\n            Token::Character { .. } => {\n                self.insert_character(token_and_info)?;\n\n                self.frameset_ok = false;\n            }\n            // A comment token\n            //\n            // Insert a comment.\n            Token::Comment { .. } => {\n                self.insert_comment(token_and_info)?;\n            }\n            // A DOCTYPE token\n            // Parse error. Ignore the token.\n            Token::Doctype { .. } => {\n                self.errors\n                    .push(Error::new(token_and_info.span, ErrorKind::StrayDoctype));\n            }\n            // A start tag whose tag name is one of: \"b\", \"big\", \"blockquote\", \"body\", \"br\",\n            // \"center\", \"code\", \"dd\", \"div\", \"dl\", \"dt\", \"em\", \"embed\", \"h1\", \"h2\", \"h3\", \"h4\",\n            // \"h5\", \"h6\", \"head\", \"hr\", \"i\", \"img\", \"li\", \"listing\", \"menu\", \"meta\", \"nobr\", \"ol\",\n            // \"p\", \"pre\", \"ruby\", \"s\", \"small\", \"span\", \"strong\", \"strike\", \"sub\", \"sup\", \"table\",\n            // \"tt\", \"u\", \"ul\", \"var\"\n            //\n            // A start tag whose tag name is \"font\", if the token has any attributes named \"color\",\n            // \"face\", or \"size\"\n            //\n            // An end tag whose tag name is \"br\", \"p\"\n            //\n            // Parse error.\n            //\n            // While the current node is not a MathML text integration point, an HTML integration\n            // point, or an element in the HTML namespace, pop elements from the stack of open\n            // elements.\n            //","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L694-L730","documentation":"process_token_in_foreign_content (crates/swc_html_parser/src/parser/mod.rs:712) flags a DOCTYPE token that arrives while the insertion point is inside an SVG/MathML subtree. The HTML5 spec says: parse error, ignore the token — nothing is appended to the tree, so this error is purely informational and parsing continues untouched.","triggerScenarios":"A `<!DOCTYPE ...>` between `<svg>` (or `<math>`) and its closing tag, e.g. `<svg><!DOCTYPE svg><rect/></svg>` or `<math><mrow><!DOCTYPE math></mrow></math>`. Typically an XML/SVG file that legitimately carries its own doctype gets embedded as a fragment after the HTML parser already entered foreign content.","commonSituations":"Inlining standalone .svg files into HTML pages, server-side includes stitching doctype-bearing partials, CMS blocks that ship their own document skeleton, naive XHTML-to-HTML string conversion.","solutions":["Strip the XML/SVG doctype from the fragment before inlining it into HTML","Keep exactly one doctype per document, emitted only by the outermost layout","If you deliberately parse SVG-as-HTML fragments, filter ErrorKind::StrayDoctype from the error list"],"exampleFix":"<!-- before -->\n<svg>\n  <!DOCTYPE svg>\n  <rect width=\"10\" height=\"10\"/>\n</svg>\n\n<!-- after -->\n<svg>\n  <rect width=\"10\" height=\"10\"/>\n</svg>","handlingStrategy":"validation","validationCode":"fn has_doctype_inside_foreign_content(html: &str) -> bool {\n    let lower = html.to_ascii_lowercase();\n    [\"<svg\", \"<math\"].iter().any(|root| {\n        lower.match_indices(root).any(|(s, _)| {\n            let close = format!(\"</{}\", &root[1..]);\n            let end = lower[s..].find(&close).map(|i| s + i).unwrap_or(lower.len());\n            lower[s..end].contains(\"<!doctype\")\n        })\n    })\n}","typeGuard":null,"tryCatchPattern":"use swc_html_parser::error::ErrorKind;\n\nlet mut errors = Vec::new();\nlet doc = swc_html_parser::parse_file_as_document(&fm, config, &mut errors)?;\n\n// Token is ignored by the spec recovery; document is complete.\nfor err in &errors {\n    if matches!(err.kind(), ErrorKind::StrayDoctype) {\n        log::warn!(\"doctype ignored inside foreign content\");\n    }\n}","preventionTips":["Inline SVG fragment content without its XML declaration or doctype","Have the outermost layout own the single document doctype","Treat StrayDoctype from inlined foreign snippets as a fixture/asset bug"],"tags":["html","parser","doctype","foreign-content","svg","mathml","swc"],"backgroundTag":"stray-doctype","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}