swc-project/swc · warning · Error

Start tag for "table" seen but the previous "table" is still

Error message

Start tag for "table" seen but the previous "table" is still open

What it means

A start tag `table` was seen while already in the "in table" insertion mode — i.e. a table is already open (parser/mod.rs:4646-4665). Nested `<table>` elements are not allowed this way; the parser records `TableSeenWhileTableOpen`, then pops the open table (if it is in table scope), resets the insertion mode, and reprocesses the token so the new table is parsed at the right level.

Source

Thrown at crates/swc_html_parser/src/parser/mod.rs:4656

                        self.process_token(token_and_info, None)?;
                    }
                    // A start tag whose tag name is "table"
                    //
                    // Parse error.
                    //
                    // If the stack of open elements does not have a table element in table scope,
                    // ignore the token.
                    //
                    // Otherwise:
                    //
                    // Pop elements from this stack until a table element has been popped from the
                    // stack.
                    //
                    // Reset the insertion mode appropriately.
                    //
                    // Reprocess the token.
                    Token::StartTag { tag_name, .. } if tag_name == "table" => {
                        self.errors.push(Error::new(
                            token_and_info.span,
                            ErrorKind::TableSeenWhileTableOpen,
                        ));

                        if !self.open_elements_stack.has_in_table_scope("table") {
                            // Ignore

                            return Ok(());
                        }

                        self.open_elements_stack
                            .pop_until_tag_name_popped(&["table"]);
                        self.reset_insertion_mode();
                        self.process_token(token_and_info, None)?;
                    }
                    // An end tag whose tag name is "table"
                    //
                    // If the stack of open elements does not have a table element in table scope,

View on GitHub (pinned to 5176682b65)

Solutions

  1. Close the previous table before starting a new one (`</table>` then `<table>`)
  2. If you actually want a nested table, put it inside a `<td>`/`<th>` cell
  3. Audit table-generating helpers for missing close tags — one omission cascades into many errors
  4. Use the error span to find where the previous table was opened

Example fix

<!-- before -->
<table><tr><td>1</td></tr><table><tr><td>2</td></tr></table></table>

<!-- after -->
<table><tr><td>1</td></tr></table>
<table><tr><td>2</td></tr></table>
Defensive patterns

Strategy: validation

Validate before calling

// Flag a <table> start while another table is still open (and not inside a cell)
fn nested_table_start(src: &str) -> bool {
    let mut stack: Vec<String> = Vec::new();
    for tag in html_tag_tokens(src) {
        match tag {
            Start(ref n) if n == "table" => {
                if stack.iter().any(|s| s == "table") && !stack.iter().any(|s| matches!(s.as_str(), "td"|"th")) {
                    return true;
                }
                stack.push(n.clone());
            }
            Start(ref n) if !is_void(n) => stack.push(n.clone()),
            End(ref n) => { while let Some(t) = stack.pop() { if t == *n { break; } } }
            _ => {}
        }
    }
    false
}

Type guard

fn is_table_while_table_open(e: &Error) -> bool {
    matches!(e.kind, ErrorKind::TableSeenWhileTableOpen)
}

Try / catch

let doc = parser.parse_document()?;
if parser.take_errors().into_iter().any(is_table_while_table_open) {
    // earlier table was force-closed; check for a missing </table> upstream
    log::warn!("nested <table> start; prior table force-closed");
}

Prevention

When it happens

Trigger: `<table><table><tr>...` — a second `<table>` start tag before the first `</table>`. Also string-built markup where a table-generating helper is called inside another table without closing it, or a missing `</table>` earlier in the source.

Common situations: Layout-table legacy code where helpers nest tables; report generators that emit a new table per row; a forgotten `</table>` makes every subsequent table appear nested, producing cascades of this error.

Related errors


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