swc-project/swc · warning · swc_html_parser::error::Error
NonSpaceCharacterInTable
NonSpaceCharacterInTable
Error message
Misplaced non-space characters inside a table
What it means
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.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:6723
fn process_token_in_table_insertion_mode_anything_else(
&mut self,
token_and_info: &mut TokenAndInfo,
) -> PResult<()> {
match &token_and_info.token {
Token::StartTag { tag_name, .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StartTagInTable(tag_name.clone()),
));
}
Token::EndTag { tag_name, .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StrayEndTag(tag_name.clone()),
));
}
Token::Character { .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::NonSpaceCharacterInTable,
));
}
_ => {
unreachable!();
}
}
let saved_foster_parenting_state = self.foster_parenting_enabled;
self.foster_parenting_enabled = true;
self.process_token_using_rules(token_and_info, InsertionMode::InBody)?;
self.foster_parenting_enabled = saved_foster_parenting_state;
Ok(())
}
View on GitHub (pinned to 5176682b65)
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
Example fix
<!-- before --> <table>Note: <tr><td>cell</td></tr></table> <!-- after --> <table><caption>Note:</caption><tr><td>cell</td></tr></table>
Defensive patterns
Strategy: validation
Validate before calling
// Reject non-whitespace text directly under <table>
function assertNoTextInTable(tableHtml: string): void {
const stripped = tableHtml.replace(/<[^>]+>/g, '');
if (/\S/.test(stripped)) throw new Error('text directly inside <table>');
} Try / catch
for err in parser.take_errors() {
if matches!(err.kind, ErrorKind::NonSpaceCharacterInTable) { /* lint-level */ }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- StartTagInTable
- No cell to close
- "{tag_name}" end tag with "select" open
- Non-space character after body
- Non-space character in "frameset"
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/35136ce964bd6f97.
Report an issue: GitHub.