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

  1. Move the text into a <td>/<th> cell or a <caption>
  2. Fix the template conditional that renders text at table level
  3. Wrap stray content in a proper cell or move it before the table
  4. 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

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


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/35136ce964bd6f97. Report an issue: GitHub.