swc-project/swc · warning · Error
Non-space character in "frameset"
Error message
Non-space character in "frameset"
What it means
A non-whitespace character token was dispatched in the 'in frameset' insertion mode. The spec says: parse error, ignore the token — frameset content cannot hold text, so the character is dropped from the tree. NonSpaceCharacterInFrameset records the loss with the character's span.
Source
Thrown at crates/swc_html_parser/src/parser/mod.rs:6433
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::EofWithUnclosedElements,
));
}
_ => {}
}
self.stopped = true;
}
// Anything else
//
// Parse error. Ignore the token.
_ => match token {
// Doctype handled above
// Comment handled above
// EOF handled above
Token::Character { .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::NonSpaceCharacterInFrameset,
));
}
Token::StartTag { tag_name, .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StrayStartTag(tag_name.clone()),
));
}
Token::EndTag { tag_name, .. } => {
self.errors.push(Error::new(
token_and_info.span,
ErrorKind::StrayEndTag(tag_name.clone()),
));
}
_ => {
unreachable!()View on GitHub (pinned to 5176682b65)
Solutions
- Wrap fallback text in <noframes>...</noframes> (or a <frame src> document).
- Remove stray text nodes from the frameset region entirely.
- If the input is third-party, filter ErrorKind::NonSpaceCharacterInFrameset; note the text is dropped, not relocated.
Example fix
<!-- before --> <frameset cols="*"> Please enable frames. <frame src="a.html"> </frameset> <!-- after --> <frameset cols="*"> <frame src="a.html"> <noframes>Please enable frames.</noframes> </frameset>
Defensive patterns
Strategy: validation
Validate before calling
// Heuristic: text (not wrapped in <noframes>) inside the frameset region.
fn has_bare_text_in_frameset(src: &str) -> bool {
let lower = src.to_ascii_lowercase();
if let (Some(s), Some(e)) = (lower.find("<frameset"), lower.find("</frameset>")) {
if e > s {
let region = &src[s..e];
// crude: strip tags, see if visible text remains
let mut text = String::new();
let mut in_tag = false;
for c in region.chars() {
match c { '<' => in_tag = true, '>' => in_tag = false, _ if !in_tag => text.push(c), _ => {} }
}
return text.chars().any(|c| !c.is_ascii_whitespace());
}
}
false
} Type guard
use swc_html_parser::error::{Error, ErrorKind};
fn is_non_space_in_frameset(err: &Error) -> bool {
matches!(err.kind(), ErrorKind::NonSpaceCharacterInFrameset)
} Try / catch
let mut errors = Vec::new();
let doc = parse_file_as_document(&fm, config, &mut errors)?;
if errors.iter().any(is_non_space_in_frameset) {
log::warn!("text inside <frameset> was dropped; use <noframes>");
} Prevention
- Put fallback text in <noframes>, never bare inside frameset.
- Remember the parser DROPS this text — verify output tree, not just the error list.
- When migrating body pages to framesets, prune text nodes from the frameset region.
When it happens
Trigger: Visible text between frameset tags, e.g. `<frameset rows="*">Your browser does not support frames</frameset>` (text directly, not inside <noframes>). The 'anything else' arm of InFrameset mode pushes the error.
Common situations: Fallback messages intended for non-frame browsers written directly into the frameset instead of inside <noframes>; copy-pasting body-style content into frameset layouts; legacy migration errors.
Related errors
- Non-space character after "frameset"
- Non-space character after body
- NonSpaceCharacterInTrailer
- Non-space characters found without seeing a doctype first, e
- End of file seen and there were open elements
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/344a1d0a180affd4.
Report an issue: GitHub.