{"record":{"id":"15c2f87f487f3fec","repo":"swc-project/swc","slug":"non-space-character-after-frameset","errorCode":null,"errorMessage":"Non-space character after \"frameset\"","messagePattern":"Non-space character after \"frameset\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":6521,"sourceCode":"                    // Process the token using the rules for the \"in head\" insertion mode.\n                    Token::StartTag { tag_name, .. } if tag_name == \"noframes\" => {\n                        self.process_token_using_rules(token_and_info, InsertionMode::InHead)?;\n                    }\n                    // An end-of-file token\n                    //\n                    // Stop parsing.\n                    Token::Eof => {\n                        self.stopped = true;\n                    }\n                    // Anything else\n                    //\n                    // Parse error. Ignore the token.\n                    _ => match token {\n                        // Doctype handled above\n                        // Comment handled above\n                        // EOF handled above\n                        Token::Character { .. } => {\n                            self.errors.push(Error::new(\n                                token_and_info.span,\n                                ErrorKind::NonSpaceCharacterAfterFrameset,\n                            ));\n                        }\n                        Token::StartTag { tag_name, .. } => {\n                            self.errors.push(Error::new(\n                                token_and_info.span,\n                                ErrorKind::StrayStartTag(tag_name.clone()),\n                            ));\n                        }\n                        Token::EndTag { tag_name, .. } => {\n                            self.errors.push(Error::new(\n                                token_and_info.span,\n                                ErrorKind::StrayEndTag(tag_name.clone()),\n                            ));\n                        }\n                        _ => {\n                            unreachable!()","sourceCodeStart":6503,"sourceCodeEnd":6539,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L6503-L6539","documentation":"A non-whitespace character token was dispatched in the 'after frameset' insertion mode. The spec says: parse error, ignore the token — text after the frameset is closed is dropped from the tree entirely. NonSpaceCharacterAfterFrameset records the discarded text with its span.","triggerScenarios":"Visible text after </frameset>, e.g. `<html><frameset cols=\"*\"><frame src=\"a.html\"></frameset>footer text</html>`. The 'anything else' arm of AfterFrameset mode pushes the error for the Character case.","commonSituations":"Footers or copyright lines appended to legacy frameset pages; SSI includes adding text at the end of the document; automated appenders writing banners after the frameset.","solutions":["Remove the trailing text, or relocate it into a <noframes> block or the frame's own document.","Fix include order so appended content lands inside a frame target, not after </frameset>.","If third-party, filter ErrorKind::NonSpaceCharacterAfterFrameset; note the text is dropped, not relocated."],"exampleFix":"<!-- before -->\n<frameset cols=\"*\"><frame src=\"a.html\"></frameset>\nCopyright 2026 Acme\n</html>\n\n<!-- after -->\n<frameset cols=\"*\">\n  <frame src=\"a.html\">\n  <noframes>Copyright 2026 Acme</noframes>\n</frameset>\n</html>","handlingStrategy":"validation","validationCode":"// Non-whitespace text between </frameset> and </html> (or EOF).\nfn has_text_between(src: &str, start_close: &str, end_close: &str) -> bool {\n    let lower = src.to_ascii_lowercase();\n    if let Some(s) = lower.find(start_close) {\n        let rest = &lower[s + start_close.len()..];\n        let end = rest.find(end_close).unwrap_or(rest.len());\n        return rest[..end].chars().any(|c| !c.is_ascii_whitespace() && c != '<');\n    }\n    false\n}\n// has_text_between(&html, \"</frameset>\", \"</html>\")","typeGuard":"use swc_html_parser::error::{Error, ErrorKind};\n\nfn is_non_space_after_frameset(err: &Error) -> bool {\n    matches!(err.kind(), ErrorKind::NonSpaceCharacterAfterFrameset)\n}","tryCatchPattern":"let mut errors = Vec::new();\nlet doc = parse_file_as_document(&fm, config, &mut errors)?;\nif errors.iter().any(is_non_space_after_frameset) {\n    log::warn!(\"text after </frameset> was dropped\");\n}","preventionTips":["Nothing visible may follow </frameset>; put fallback content in <noframes>.","Check include order in SSI/CGI pipelines that append to frameset pages.","This text is dropped, not relocated — verify the output tree."],"tags":["html","parser","swc","frameset","text-node","parse-error"],"backgroundTag":"content-after-frameset","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"}