swc-project/swc · error · swc_xml_parser::error::Error

UnexpectedTokenInStartPhase

UnexpectedTokenInStartPhase

Error message

Unexpected token in start phase

What it means

swc_xml_parser processes the document in a start phase before the root element where only the doctype, comments, processing instructions and whitespace are legal. When a CDATA token arrives in that phase, `UnexpectedTokenInStartPhase` is recorded (crates/swc_xml_parser/src/parser/mod.rs:272) — CDATA sections are only allowed inside element content. The parser still appends the CDATA node to the document and moves on, so the diagnostic is recoverable.

Source

Thrown at crates/swc_xml_parser/src/parser/mod.rs:272

                    self.append_node(self.document.as_ref().unwrap(), element.clone());
                    self.open_elements_stack.items.push(element);
                    self.phase = Phase::MainPhase;
                }
                Token::EmptyTag { .. } => {
                    let element = self.create_element_for_token(token_and_info.clone());

                    self.append_node(self.document.as_ref().unwrap(), element);
                    self.phase = Phase::EndPhase;
                }
                Token::Comment { .. } => {
                    self.append_comment_to_doc(token_and_info)?;
                }
                Token::ProcessingInstruction { .. } => {
                    self.append_processing_instruction_to_doc(token_and_info)?;
                }
                Token::Cdata { .. } => {
                    self.errors.push(Error::new(
                        token_and_info.span,
                        ErrorKind::UnexpectedTokenInStartPhase,
                    ));

                    self.append_cdata_to_doc(token_and_info)?;
                }
                Token::Character { value, .. } => {
                    if !is_whitespace(*value) {
                        self.errors.push(Error::new(
                            token_and_info.span,
                            ErrorKind::UnexpectedCharacter,
                        ));
                    }
                }
                Token::Eof => {
                    self.errors.push(Error::new(
                        token_and_info.span,
                        ErrorKind::UnexpectedEofInStartPhase,

View on GitHub (pinned to 5176682b65)

Solutions

  1. Move the CDATA section inside the root element
  2. If the file is a fragment, wrap it in a root element before parsing
  3. Convert leading metadata text to a comment or processing instruction
  4. Pre-validate with xmllint so prolog errors surface before your pipeline

Example fix

<!-- before -->
<![CDATA[raw]]><root><a/></root>
<!-- after -->
<root><![CDATA[raw]]><a/></root>
Defensive patterns

Strategy: validation

Validate before calling

// Reject CDATA or stray tags before the root element
function assertCleanProlog(xml: string): void {
  const rootIdx = xml.search(/<[a-zA-Z_:]/);
  const prolog = rootIdx === -1 ? xml : xml.slice(0, rootIdx);
  const cleaned = prolog.replace(/<\?[\s\S]*?\?>|<!--([\s\S]*?)-->|<!DOCTYPE[^>]*>/g, '');
  if (/\S|<!\[CDATA\[/.test(cleaned)) throw new Error('illegal content before root element');
}

Try / catch

for err in parser.take_errors() {
    if matches!(err.kind, ErrorKind::UnexpectedTokenInStartPhase) {
        // CDATA was still appended to the document; strip it downstream if unwanted
    }
}

Prevention

When it happens

Trigger: Parsing a document whose prolog contains a CDATA section, e.g. `<![CDATA[raw]]><root/>` — the CDATA token hits the start-phase match before the root element is created.

Common situations: Concatenating a CDATA payload ahead of the root element in generated files; fragments pasted above `<root>`; malformed exports that put escaped/legacy content before the document element.

Understand the failure class

Related errors


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