swc-project/swc · warning · Error
Start tag "{tag_name}" seen in "table"
Error message
Start tag "{tag_name}" seen in "table" What it means
A start tag `input` with `type=hidden` was seen in the "in table" insertion mode (parser/mod.rs:4755-4790). Hidden inputs are the only inputs allowed in table content (a spec carve-out so forms can embed data in tables); it is still a parse error. The parser records `StartTagInTable("input")`, inserts the element, and immediately pops it (input is void). Non-hidden inputs take the foster-parenting path instead and produce different errors.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:4775
let is_self_closing = *is_self_closing;
let input_type =
attributes.iter().find(|attribute| attribute.name == "type");
let is_hidden = match &input_type {
Some(input_type) => match &input_type.value {
Some(value) if value.as_ref().eq_ignore_ascii_case("hidden") => {
true
}
_ => false,
},
_ => false,
};
if input_type.is_none() || !is_hidden {
self.process_token_in_table_insertion_mode_anything_else(
token_and_info,
)?;
} else {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StartTagInTable(tag_name.clone()),
));
self.insert_html_element(token_and_info)?;
self.open_elements_stack.pop();
if is_self_closing {
token_and_info.acknowledged = true;
}
}
}
// A start tag whose tag name is "form"
//
// Parse error.
//
// If there is a template element on the stack of open elements, or if the form
// element pointer is not null, ignore the token.View on GitHub (pinned to 5176682b65)
Solutions
- Move the hidden input into a cell: `<td><input type="hidden" ...></td>` (or outside the table entirely)
- Emit framework-injected hidden fields before the `<table>` opens
- Keep the placement only if you deliberately rely on the spec carve-out — the tree is still correct — but expect the parse-error warning
- Filter `StartTagInTable` from take_errors() when ingesting third-party grid HTML you cannot change
Example fix
<!-- before --> <table><input type="hidden" name="id" value="7"><tr><td>x</td></tr></table> <!-- after --> <input type="hidden" name="id" value="7"> <table><tr><td>x</td></tr></table>
Defensive patterns
Strategy: validation
Validate before calling
// Reject <input type=hidden> (or any input) placed directly under table/tbody/tr
fn input_directly_in_table(src: &str) -> bool {
let mut stack: Vec<String> = Vec::new();
for tag in html_tag_tokens(src) {
match tag {
Start(ref n) if matches!(n.as_str(), "table"|"tbody"|"thead"|"tfoot"|"tr") => stack.push(n.clone()),
End(ref n) if matches!(n.as_str(), "table"|"tbody"|"thead"|"tfoot"|"tr") => {
while let Some(t) = stack.pop() { if t == *n { break; } }
}
Start(ref n) if n == "input" => {
if stack.last().is_some() { return true; } // no td/th between input and table tags
}
_ => {}
}
}
false
} Type guard
fn is_hidden_input_in_table(e: &Error) -> bool {
matches!(e.kind, ErrorKind::StartTagInTable(ref t) if &**t == "input")
} Try / catch
let doc = parser.parse_document()?;
if parser.take_errors().into_iter().any(is_hidden_input_in_table) {
// tree is still correct (spec carve-out for hidden inputs) — report only
log::warn!("<input type=hidden> directly in table markup");
} Prevention
- Emit framework hidden fields (CSRF, pagination) before the table opens
- Or place them inside a td/th cell
- When ingesting third-party grids, whitelist StartTagInTable('input') as accepted noise
When it happens
Trigger: `<table><input type="hidden" name="row_id" value="7"><tr>...` — an `<input type=hidden>` placed directly inside `<table>`, `<tbody>`, or `<tr>` rather than inside a `<td>`/`<th>` cell. Any other input type (or missing type) does not hit this arm.
Common situations: Server-rendered grids that attach per-table form data (pagination tokens, CSRF fields) directly under `<table>`; ASP.NET WebForms-era patterns; auto-injected hidden fields from frameworks that assume body context.
Related errors
- Start tag for "table" seen but the previous "table" is still
- Stray start tag "{tag_name}"
- failed to parse input as document fragment
- failed to parse input as document
- failed to parse input as document fragment
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/ad080844830ad768.
Report an issue: GitHub.