{"record":{"id":"90ad130718ae9632","repo":"swc-project/swc","slug":"straydoctype","errorCode":"StrayDoctype","errorMessage":"Stray doctype","messagePattern":"Stray doctype","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":1702,"sourceCode":"                    // Insert the character.\n                    Token::Character {\n                        value: '\\x09' | '\\x0A' | '\\x0C' | '\\x0D' | '\\x20',\n                        ..\n                    } => {\n                        self.insert_character(token_and_info)?;\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                    //\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 \"html\"\n                    //\n                    // Process the token using the rules for the \"in body\" insertion mode.\n                    Token::StartTag { tag_name, .. } if tag_name == \"html\" => {\n                        self.process_token_using_rules(token_and_info, InsertionMode::InBody)?;\n                    }\n                    // A start tag whose tag name is one of: \"base\", \"basefont\", \"bgsound\", \"link\"\n                    //\n                    // Insert an HTML element for the token. Immediately pop the current node off\n                    // the stack of open elements.\n                    //\n                    // Acknowledge the token's self-closing flag, if it is set.\n                    Token::StartTag {\n                        tag_name,\n                        is_self_closing,\n                        ..\n                    } if matches!(&**tag_name, \"base\" | \"basefont\" | \"bgsound\" | \"link\") => {","sourceCodeStart":1684,"sourceCodeEnd":1720,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L1684-L1720","documentation":"A DOCTYPE token arrived while the parser was in the 'in head' insertion mode (crates/swc_html_parser/src/parser/mod.rs:1702) — inside the head element. Spec: parse error, ignore the token. This is the most common StrayDoctype in practice: a duplicated doctype appearing after head has started.","triggerScenarios":"`<!DOCTYPE html><html><head><meta charset=\"utf-8\"><!DOCTYPE html>` or any doctype token whose preceding content already opened head. Comments and metadata before it do not close head, so the stray doctype is still processed by in-head rules.","commonSituations":"A doctype line inside a shared <head> include partial, meta-tag snippets that carry a full document skeleton, duplicate doctypes from wrapper + content concatenation.","solutions":["Delete the doctype from head-included partials; keep exactly one at the document top","Audit includes/snippets for embedded document skeletons (doctype, html, head)","Filter ErrorKind::StrayDoctype when duplicates are acceptable"],"exampleFix":"<!-- before -->\n<head>\n  <meta charset=\"utf-8\">\n  <!DOCTYPE html>\n  <title>t</title>\n</head>\n\n<!-- after -->\n<head>\n  <meta charset=\"utf-8\">\n  <title>t</title>\n</head>","handlingStrategy":"validation","validationCode":"fn doctype_inside_head(html: &str) -> bool {\n    let lower = html.to_ascii_lowercase();\n    match (lower.find(\"<head\"), lower.rfind(\"</head\")) {\n        (Some(open), Some(close)) => lower[open..close].contains(\"<!doctype\"),\n        (Some(open), None) => lower[open..].contains(\"<!doctype\"),\n        _ => false,\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\nfor err in &errors {\n    if matches!(err.kind(), ErrorKind::StrayDoctype) {\n        // Ignored inside head; head content parsed normally.\n        log::warn!(\"doctype inside <head> ignored\");\n    }\n}","preventionTips":["Head includes must contain only head-legal elements (meta/link/title/style/script)","Never paste a full document skeleton into a head partial","Lint for a second `<!doctype` occurrence anywhere in the file"],"tags":["html","parser","doctype","head","duplicate","insertion-mode","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-14T00:17:10.932Z"}