{"record":{"id":"48608eabb865f750","repo":"swc-project/swc","slug":"end-of-file-seen-without-seeing-a-doctype-first-e","errorCode":null,"errorMessage":"End of file seen without seeing a doctype first, expected \"<!DOCTYPE html>\"","messagePattern":"End of file seen without seeing a doctype first, expected \"<!DOCTYPE html>\"","errorType":"exception","errorClass":"swc_html_parser::error::Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":1432,"sourceCode":"                                    self.errors.push(Error::new(\n                                        token_and_info.span,\n                                        ErrorKind::StartTagWithoutDoctype,\n                                    ));\n                                }\n                                Token::EndTag { .. } => {\n                                    self.errors.push(Error::new(\n                                        token_and_info.span,\n                                        ErrorKind::EndTagSeenWithoutDoctype,\n                                    ));\n                                }\n                                Token::Character { .. } => {\n                                    self.errors.push(Error::new(\n                                        token_and_info.span,\n                                        ErrorKind::NonSpaceCharacterWithoutDoctype,\n                                    ));\n                                }\n                                Token::Eof => {\n                                    self.errors.push(Error::new(\n                                        token_and_info.span,\n                                        ErrorKind::EofWithoutDoctype,\n                                    ));\n                                }\n                                _ => {\n                                    unreachable!();\n                                }\n                            }\n\n                            self.set_document_mode(DocumentMode::Quirks);\n                        }\n\n                        self.insertion_mode = InsertionMode::BeforeHtml;\n                        self.process_token(token_and_info, None)?;\n                    }\n                }\n            }\n            // The \"before html\" insertion mode","sourceCodeStart":1414,"sourceCodeEnd":1450,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L1414-L1450","documentation":"Initial insertion mode, 'anything else' branch (crates/swc_html_parser/src/parser/mod.rs:1432): the token stream reached EOF before any doctype (and before any other content), with iframe_srcdoc false. Parse error; the document is set to quirks mode. An empty or whitespace/comment-only input is the classic trigger.","triggerScenarios":"parse_document on an empty string, a file containing only whitespace, or only comments (e.g. `<!-- generated -->` with nothing after it).","commonSituations":"Empty files from failed upstream fetches, placeholder/template files not yet filled, zero-length responses parsed as HTML, comment-only server-side files whose output is empty.","solutions":["Guard against empty input before parsing and skip/short-circuit","Set ParserConfig { iframe_srcdoc: true, .. } if empty srcdoc documents are legitimate in your flow","Treat EofWithoutDoctype on empty input as an upstream data problem: fetch/validate the source"],"exampleFix":"// before\nlet fm = cm.new_source_file(file.into(), String::new());\nlet doc = parse_file_as_document(&fm, config, &mut errors)?; // EofWithoutDoctype + quirks\n\n// after\nif html.trim().is_empty() {\n    return Ok(empty_document());\n}\nlet fm = cm.new_source_file(file.into(), html);\nlet doc = parse_file_as_document(&fm, config, &mut errors)?;","handlingStrategy":"validation","validationCode":"fn is_empty_document(html: &str) -> bool {\n    let mut rest = html.trim_start();\n    while let Some(t) = rest.strip_prefix(\"<!--\") {\n        match t.find(\"-->\") {\n            Some(i) => rest = t[i + 3..].trim_start(),\n            None => return true,\n        }\n    }\n    rest.is_empty()\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::EofWithoutDoctype) {\n        log::warn!(\"empty/whitespace-only input parsed as document\");\n    }\n}","preventionTips":["Short-circuit on empty input instead of parsing it","Verify upstream fetches produce non-empty bodies before HTML parsing","Set iframe_srcdoc = true when empty srcdoc documents are expected"],"tags":["html","parser","doctype","empty-input","eof","quirks-mode","swc"],"backgroundTag":"missing-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"}