swc-project/swc · warning · swc_html_parser::error::Error

NonSpaceCharacterInTrailer

NonSpaceCharacterInTrailer

Error message

Non-space character in page trailer

What it means

A non-whitespace character token arrived in the 'after after body' insertion mode, i.e. visible text after </html>. This is the spec's 'non-space-character-in-trailer' parse error: the parser switches back to 'in body' and reprocesses, so the text is appended to body despite appearing after the document end. NonSpaceCharacterInTrailer records the misplaced character.

Source

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

                    Token::StartTag { tag_name, .. } if tag_name == "html" => {
                        self.process_token_using_rules(token_and_info, InsertionMode::InBody)?;
                    }
                    // An end-of-file token
                    //
                    // Stop parsing.
                    Token::Eof => {
                        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::NonSpaceCharacterInTrailer,
                                ));
                            }
                            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

  1. Move the stray text before </body> in the source.
  2. Fix the builder/injector to insert content inside body rather than after </html>.
  3. If third-party and the recovered placement (text inside body) is fine, filter ErrorKind::NonSpaceCharacterInTrailer from the errors vec.

Example fix

<!-- before -->
<html><body>main</body></html>
appended text

<!-- after -->
<html><body>main
appended text
</body></html>
Defensive patterns

Strategy: validation

Validate before calling

// Non-whitespace after the last </html> is page-trailer content.
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)
}
// has_text_after(&html, "</html>")

Type guard

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

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

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_trailer) {
    log::warn!("text after </html> was relocated into body");
}

Prevention

When it happens

Trigger: Text after the html close tag, e.g. `<html><body>x</body></html>trailing`. The 'anything else' arm of AfterAfterBody mode (crates/swc_html_parser/src/parser/mod.rs:6593) pushes the error, sets insertion_mode = InBody, and reprocesses the token.

Common situations: Tracking pixels and text nodes appended after </html> by append-to-file tooling; naive template concatenation; whitespace-trimming build steps that expose stray characters after the document close.

Related errors


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