swc-project/swc · warning · Error

Non-space character after body

Error message

Non-space character after body

What it means

A character token that is not whitespace (not TAB/LF/FF/CR/SPACE) was dispatched in the 'after body' insertion mode, i.e. visible text appeared after </body>. The spec says: parse error, switch to 'in body' and reprocess, so the text still ends up appended inside body. The error (NonSpaceCharacterAfterBody) records the misplaced character with its span.

Source

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

                    //
                    // Stop parsing.
                    Token::Eof => {
                        self.update_end_tag_span(
                            self.open_elements_stack.items.last(),
                            token_and_info.span,
                        );
                        self.stopped = true;
                    }
                    // Anything else
                    //
                    // Parse error. Switch the insertion mode to "in body" and reprocess 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::NonSpaceCharacterAfterBody,
                                ));
                            }
                            Token::StartTag { tag_name, .. } => {
                                self.errors.push(Error::new(
                                    token_and_info.span,
                                    ErrorKind::StrayStartTag(tag_name.clone()),
                                ));
                            }
                            Token::EndTag { .. } => {
                                self.errors.push(Error::new(
                                    token_and_info.span,
                                    ErrorKind::EndTagAfterBody,
                                ));
                            }
                            _ => {
                                unreachable!();

View on GitHub (pinned to 5176682b65)

Solutions

  1. Move the stray text before </body> in the source.
  2. Fix the generator/injector so it inserts content at the end of body, not after the closing tag.
  3. If the markup is third-party and the recovered tree (text inside body) is acceptable, filter ErrorKind::NonSpaceCharacterAfterBody from the errors vec.

Example fix

<!-- before -->
<body>content</body>
tracker-pixel-text
</html>

<!-- after -->
<body>content
tracker-pixel-text
</body>
</html>
Defensive patterns

Strategy: validation

Validate before calling

// Detect non-whitespace content after the last </body>.
fn has_text_after(src: &str, close: &str) -> bool {
    let lower = src.to_ascii_lowercase();
    lower.rfind(close)
        .map(|i| lower[i + close.len()..].chars().any(|c| !c.is_ascii_whitespace()))
        .unwrap_or(false)
}

if has_text_after(&html_src, "</body>") { /* fix injector before parsing */ }

Type guard

use swc_html_parser::error::{Error, ErrorKind};

fn is_non_space_after_body(err: &Error) -> bool {
    matches!(err.kind(), ErrorKind::NonSpaceCharacterAfterBody)
}

Try / catch

let mut errors = Vec::new();
let doc = parse_file_as_document(&fm, config, &mut errors)?;
// Recovery moves the text into body; decide whether that is acceptable.
if errors.iter().any(is_non_space_after_body) {
    log::warn!("text after </body> was relocated into body");
}

Prevention

When it happens

Trigger: Any non-whitespace text node after the body close tag, e.g. `<html><body>ok</body>oops`. Only the first reprocessed character token reports; the follow-up tokens are then handled in 'in body' mode without error.

Common situations: Analytics/tracking snippets or banner text appended after </body> by reverse proxies; string-concatenation page builders that lose ordering; build steps that inject content at 'end of file' rather than 'end of body'.

Related errors


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