{"record":{"id":"49de3ae91a30decb","repo":"swc-project/swc","slug":"end-of-file-seen-when-expecting-text-or-an-end-tag","errorCode":null,"errorMessage":"End of file seen when expecting text or an end tag","messagePattern":"End of file seen when expecting text or an end tag","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":4399,"sourceCode":"                    //\n                    // Insert the token's character.\n                    Token::Character { .. } => {\n                        self.insert_character(token_and_info)?;\n                    }\n                    // An end-of-file token\n                    //\n                    // Parse error.\n                    //\n                    // If the current node is a script element, mark the script element as \"already\n                    // started\".\n                    //\n                    // Pop the current node off the stack of open elements.\n                    //\n                    // Switch the insertion mode to the original insertion mode and reprocess the\n                    // token.\n                    Token::Eof => {\n                        self.errors\n                            .push(Error::new(token_and_info.span, ErrorKind::EofInText));\n\n                        let popped = self.open_elements_stack.pop();\n\n                        self.update_end_tag_span(popped.as_ref(), token_and_info.span);\n                        self.insertion_mode = self.original_insertion_mode.clone();\n                        self.process_token(token_and_info, None)?;\n                    }\n                    // An end tag whose tag name is \"script\"\n                    //\n                    // If the active speculative HTML parser is null and the JavaScript execution\n                    // context stack is empty, then perform a microtask checkpoint.\n                    //\n                    // Let script be the current node (which will be a script element).\n                    //\n                    // Pop the current node off the stack of open elements.\n                    //\n                    // Switch the insertion mode to the original insertion mode.\n                    //","sourceCodeStart":4381,"sourceCodeEnd":4417,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L4381-L4417","documentation":"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.","triggerScenarios":"`<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.","commonSituations":"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.","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)"],"exampleFix":"<!-- before -->\n<title>My page\n\n<!-- after -->\n<title>My page</title>","handlingStrategy":"validation","validationCode":"// Detect an unterminated text-mode element before parsing\nfn eof_in_text_element(src: &str) -> bool {\n    for el in [\"title\", \"textarea\", \"style\", \"xmp\", \"iframe\", \"noembed\", \"noframes\", \"noscript\", \"script\"] {\n        let open = format!(\"<{el}\");\n        let close = format!(\"</{el}\");\n        if src.contains(&open) {\n            let last_open = src.rfind(&open).unwrap_or(0);\n            let after = &src[last_open..];\n            if !after.contains(&close) { return true; }\n        }\n    }\n    false\n}","typeGuard":"fn is_eof_in_text(e: &Error) -> bool {\n    matches!(e.kind, ErrorKind::EofInText)\n}","tryCatchPattern":"let doc = parser.parse_document()?;\nif parser.take_errors().into_iter().any(is_eof_in_text) {\n    // input was truncated — everything after this point is lost; do not ship the tree\n    return Err(SourceIntegrity::TruncatedInput);\n}","preventionTips":["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"],"tags":["html","parser","eof","truncated-input","textarea","title","text-mode"],"backgroundTag":"eof-in-unterminated-element","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"}