swc-project/swc · error · Error
End of file seen when expecting text or an end tag
Error message
End of file seen when expecting text or an end tag
What it means
EOF was reached while the insertion mode was "text" — i.e. the parser was sitting inside an element whose content is consumed as raw text (e.g. `<title>`, `<textarea>`, or any element that switched to generic text parsing) and its end tag never came (parser/mod.rs:4386-4406). This is the `EofInText` parse error; recovery pops the element, restores the original insertion mode, and reprocesses the EOF token so the rest of document close-out runs normally.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:4399
//
// Insert the token's character.
Token::Character { .. } => {
self.insert_character(token_and_info)?;
}
// An end-of-file token
//
// Parse error.
//
// If the current node is a script element, mark the script element as "already
// started".
//
// Pop the current node off the stack of open elements.
//
// Switch the insertion mode to the original insertion mode and reprocess the
// token.
Token::Eof => {
self.errors
.push(Error::new(token_and_info.span, ErrorKind::EofInText));
let popped = self.open_elements_stack.pop();
self.update_end_tag_span(popped.as_ref(), token_and_info.span);
self.insertion_mode = self.original_insertion_mode.clone();
self.process_token(token_and_info, None)?;
}
// An end tag whose tag name is "script"
//
// If the active speculative HTML parser is null and the JavaScript execution
// context stack is empty, then perform a microtask checkpoint.
//
// Let script be the current node (which will be a script element).
//
// Pop the current node off the stack of open elements.
//
// Switch the insertion mode to the original insertion mode.
//View on GitHub (pinned to 5176682b65)
Solutions
- Add the missing end tag (`</title>`, `</textarea>`, etc.) for the element named by the recovery
- Check for truncation: verify file size / Content-Length and re-fetch or re-generate the source
- Fix template partials so every text-mode element is closed within the same partial
- Treat EofInText as a hard data-integrity signal in pipelines (unlike cosmetic tag typos)
Example fix
<!-- before --> <title>My page <!-- after --> <title>My page</title>
Defensive patterns
Strategy: validation
Validate before calling
// Detect an unterminated text-mode element before parsing
fn eof_in_text_element(src: &str) -> bool {
for el in ["title", "textarea", "style", "xmp", "iframe", "noembed", "noframes", "noscript", "script"] {
let open = format!("<{el}");
let close = format!("</{el}");
if src.contains(&open) {
let last_open = src.rfind(&open).unwrap_or(0);
let after = &src[last_open..];
if !after.contains(&close) { return true; }
}
}
false
} Type guard
fn is_eof_in_text(e: &Error) -> bool {
matches!(e.kind, ErrorKind::EofInText)
} Try / catch
let doc = parser.parse_document()?;
if parser.take_errors().into_iter().any(is_eof_in_text) {
// input was truncated — everything after this point is lost; do not ship the tree
return Err(SourceIntegrity::TruncatedInput);
} Prevention
- Verify Content-Length / file size before parsing remote or uploaded HTML
- Treat EofInText as a data-integrity failure, not a cosmetic warning
- Close title/textarea and other text-mode elements inside the same template partial
- Re-fetch or re-generate truncated sources instead of accepting the recovered tree
When it happens
Trigger: `<title>My page` at end of file, `<textarea>user input` with no `</textarea>`, truncated HTML files, or template concatenation that drops a close tag for a text-mode element.
Common situations: Truncated uploads/downloads, network reads cut short, template partials stitched without close tags, and user-generated content saved mid-edit. The trailing text is kept as the element's text content, but everything after the truncation point is gone.
Related errors
- Unexpected end of file
- End of file seen without seeing a doctype first, expected "<
- End of file seen and there were open elements
- The requested module '{specifier}' does not provide an expor
- attempted to ${action} private field on non-instance
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/49de3ae91a30decb.
Report an issue: GitHub.