{"record":{"id":"35136ce964bd6f97","repo":"swc-project/swc","slug":"nonspacecharacterintable","errorCode":"NonSpaceCharacterInTable","errorMessage":"Misplaced non-space characters inside a table","messagePattern":"Misplaced non-space characters inside a table","errorType":"validation","errorClass":"swc_html_parser::error::Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":6723,"sourceCode":"    fn process_token_in_table_insertion_mode_anything_else(\n        &mut self,\n        token_and_info: &mut TokenAndInfo,\n    ) -> PResult<()> {\n        match &token_and_info.token {\n            Token::StartTag { tag_name, .. } => {\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::StartTagInTable(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            Token::Character { .. } => {\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::NonSpaceCharacterInTable,\n                ));\n            }\n            _ => {\n                unreachable!();\n            }\n        }\n\n        let saved_foster_parenting_state = self.foster_parenting_enabled;\n\n        self.foster_parenting_enabled = true;\n        self.process_token_using_rules(token_and_info, InsertionMode::InBody)?;\n        self.foster_parenting_enabled = saved_foster_parenting_state;\n\n        Ok(())\n    }\n","sourceCodeStart":6705,"sourceCodeEnd":6741,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L6705-L6741","documentation":"Text (non-whitespace character tokens) is not allowed as a direct child of `<table>` per the HTML standard; the anything-else branch of the in-table insertion mode (crates/swc_html_parser/src/parser/mod.rs:6723) reports `NonSpaceCharacterInTable` and then foster-parents the text so it is rendered before the table. Whitespace-only text does not trigger this.","triggerScenarios":"Parsing `<table>foo<tr>...` — character data appearing directly under `<table>` (not inside a cell, caption, or other permitted container) reaches the Character branch of the in-table anything-else handler.","commonSituations":"Copy-pasted table HTML where a stray word sits between `<table>` and `<tr>`; template conditionals that render text when a variable is empty; whitespace-trimming bugs that leave real text at the table level; i18n strings injected at the wrong place.","solutions":["Move the text into a <td>/<th> cell or a <caption>","Fix the template conditional that renders text at table level","Wrap stray content in a proper cell or move it before the table","Keep it as a warning in HTML linting — output is recovered via foster parenting"],"exampleFix":"<!-- before -->\n<table>Note: <tr><td>cell</td></tr></table>\n<!-- after -->\n<table><caption>Note:</caption><tr><td>cell</td></tr></table>","handlingStrategy":"validation","validationCode":"// Reject non-whitespace text directly under <table>\nfunction assertNoTextInTable(tableHtml: string): void {\n  const stripped = tableHtml.replace(/<[^>]+>/g, '');\n  if (/\\S/.test(stripped)) throw new Error('text directly inside <table>');\n}","typeGuard":null,"tryCatchPattern":"for err in parser.take_errors() {\n    if matches!(err.kind, ErrorKind::NonSpaceCharacterInTable) { /* lint-level */ }\n}","preventionTips":["Put visible text in cells or a caption, never between table tags","Guard template conditionals so empty variables emit nothing at table level","Foster parenting moves the text before the table — check rendered output after recovery"],"tags":["html","table","text-node","foster-parenting","parse-error"],"backgroundTag":"html5-parse-error","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"}