swc-project/swc · warning · swc_html_parser::error::Error
Non conforming doctype
Error message
Non conforming doctype
What it means
The DOCTYPE token handled in the initial insertion mode (crates/swc_html_parser/src/parser/mod.rs:1357) is not the one conforming form: the name must equal 'html' ASCII-case-insensitively, there must be no public identifier, and the system identifier must be absent or exactly "about:legacy-compat". The parser still appends the DocumentType node to the document and computes quirks/limited-quirks mode from the public/system id tables, but records NonConformingDoctype.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:1357
//
// Then, switch the insertion mode to "before html".
Token::Doctype {
name,
public_id,
system_id,
force_quirks,
raw,
..
} => {
let is_html_name =
matches!(name, Some(name) if name.eq_ignore_ascii_case("html"));
let is_conforming_doctype = is_html_name
&& public_id.is_none()
&& (system_id.is_none()
|| matches!(system_id, Some(system_id) if system_id == "about:legacy-compat"));
if !is_conforming_doctype {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::NonConformingDoctype,
));
}
let document_type = Node::new(
Data::DocumentType {
name: name.clone(),
public_id: public_id.clone(),
system_id: system_id.clone(),
raw: raw.clone(),
},
token_and_info.span,
);
self.append_node(self.document.as_ref().unwrap(), document_type);
if !self.config.iframe_srcdocView on GitHub (pinned to 5176682b65)
Solutions
- Replace the legacy doctype with `<!DOCTYPE html>`
- If the legacy doctype is intentional (archival content), filter ErrorKind::NonConformingDoctype and check the returned document's mode before applying quirks-sensitive processing
- For pure AST extraction keep it as-is: the DocumentType node with name/public_id/system_id is still emitted correctly
Example fix
<!-- before --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">...</html> <!-- after --> <!DOCTYPE html> <html lang="en">...</html>
Defensive patterns
Strategy: validation
Validate before calling
fn has_conforming_doctype(html: &str) -> bool {
let lower = html.trim_start().to_ascii_lowercase();
// Conforming shapes: <!DOCTYPE html> or
// <!DOCTYPE html SYSTEM "about:legacy-compat"> — never PUBLIC.
if !lower.starts_with("<!doctype html") {
return false;
}
let rest = lower["<!doctype html".len()..].trim_start();
rest.is_empty()
|| rest.starts_with('>')
|| rest.starts_with("system \"about:legacy-compat\"")
} 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::NonConformingDoctype) {
// Recovery kept the doctype node; mode may be Quirks:
log::warn!("non-conforming doctype; document mode = {:?}", doc.mode);
}
} Prevention
- Standardize templates on `<!DOCTYPE html>`
- Treat any PUBLIC identifier in a doctype as a migration leftover
- Assert Document::mode == NoQuirks in layout-sensitive pipelines
When it happens
Trigger: Any doctype with a PUBLIC identifier — XHTML 1.0 (`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">`), HTML 4.01 flavors — or a SYSTEM identifier other than "about:legacy-compat".
Common situations: Legacy pages, frameworks defaulting to XHTML doctypes, migrated JSP/PHP/ASP templates, fixtures copied from old W3C examples. Watch the side effect: these doctypes often flip Document.mode to Quirks/LimitedQuirks, which changes how downstream layout or serialization treats the tree.
Related errors
- 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
- End of file seen without seeing a doctype first, expected "<
- Stray doctype
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/6d326173d44c08ec.
Report an issue: GitHub.