swc-project/swc · warning · swc_html_parser::error::Error
End of file seen without seeing a doctype first, expected "<
Error message
End of file seen without seeing a doctype first, expected "<!DOCTYPE html>"
What it means
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.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:1432
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StartTagWithoutDoctype,
));
}
Token::EndTag { .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::EndTagSeenWithoutDoctype,
));
}
Token::Character { .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::NonSpaceCharacterWithoutDoctype,
));
}
Token::Eof => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::EofWithoutDoctype,
));
}
_ => {
unreachable!();
}
}
self.set_document_mode(DocumentMode::Quirks);
}
self.insertion_mode = InsertionMode::BeforeHtml;
self.process_token(token_and_info, None)?;
}
}
}
// The "before html" insertion modeView on GitHub (pinned to 5176682b65)
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
Example fix
// before
let fm = cm.new_source_file(file.into(), String::new());
let doc = parse_file_as_document(&fm, config, &mut errors)?; // EofWithoutDoctype + quirks
// after
if html.trim().is_empty() {
return Ok(empty_document());
}
let fm = cm.new_source_file(file.into(), html);
let doc = parse_file_as_document(&fm, config, &mut errors)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_empty_document(html: &str) -> bool {
let mut rest = html.trim_start();
while let Some(t) = rest.strip_prefix("<!--") {
match t.find("-->") {
Some(i) => rest = t[i + 3..].trim_start(),
None => return true,
}
}
rest.is_empty()
} Try / catch
use swc_html_parser::error::ErrorKind;
let mut errors = Vec::new();
let doc = swc_html_parser::parse_file_as_document(&fm, config, &mut errors)?;
for err in &errors {
if matches!(err.kind(), ErrorKind::EofWithoutDoctype) {
log::warn!("empty/whitespace-only input parsed as document");
}
} Prevention
- 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
When it happens
Trigger: parse_document on an empty string, a file containing only whitespace, or only comments (e.g. `<!-- generated -->` with nothing after it).
Common situations: 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.
Related errors
- Non conforming doctype
- Start tag seen without seeing a doctype first, expected "<!D
- End tag seen without seeing a doctype first, expected "<!DOC
- Non-space characters found without seeing a doctype first, e
- Stray doctype
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/48608eabb865f750.
Report an issue: GitHub.