swc-project/swc · error · TypeError

attempted to ${action} private field on non-instance

Error message

attempted to ${action} private field on non-instance

What it means

The input ended while the parser was in the Main phase, meaning the open-elements stack still had unclosed elements when EOF arrived. The parser records this recoverable error with the EOF span and switches to the End phase so trailing comments/PIs are still handled. The document is produced with elements that have no (matching) end span, so their spans fall back to child spans or the start span.

Source

Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_class_extract_field_descriptor.rs:11

// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.

use super::{HelperDef, HelperName};

pub const DEF: HelperDef = HelperDef {
    name: HelperName::class_extract_field_descriptor,
    local: "_class_extract_field_descriptor",
    import_path: "@swc/helpers/_/_class_extract_field_descriptor",
    #[cfg(feature = "inline-helpers")]
    source: r#"function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");

    return privateMap.get(receiver);
}
"#,
    #[cfg(feature = "inline-helpers")]
    deps: super::HelperBitmap::from_bits(0x00000000000000000000000000400000),
};

#[cfg(feature = "inline-helpers")]
pub fn stmts() -> &'static [swc_ecma_ast::Stmt] {
    static STMTS: once_cell::sync::Lazy<Vec<swc_ecma_ast::Stmt>> =
        once_cell::sync::Lazy::new(|| super::super::parse(DEF.source, DEF.import_path));
    &STMTS
}

View on GitHub (pinned to 5176682b65)

Solutions

  1. Check the tail of the input at the error span - it will point at the end of file, so the real problem is the last unclosed element; walk up from it and add the missing end tags.
  2. Verify upstream producers write and flush the complete document (compare expected byte length, re-read the file after the writer closes).
  3. If you are parsing chunks, buffer until the stream is complete or use a streaming parser designed for partial input.
  4. After parsing, treat ErrorKind::UnexpectedEofInMainPhase as fatal for downstream consumers because element spans and end-tag spans are incomplete.

Example fix

<!-- before: EOF while root/child still open -->
<root>
  <child>text

<!-- after -->
<root>
  <child>text</child>
</root>
Defensive patterns

Strategy: validation

Validate before calling

use swc_xml_parser::error::ErrorKind;

let mut errors = Vec::new();
let doc = swc_xml_parser::parse_file_as_document(&fm, config, &mut errors)?;
if errors
    .iter()
    .any(|e| matches!(e.kind(), ErrorKind::UnexpectedEofInMainPhase))
{
    return Err("input truncated: unclosed elements at EOF".into());
}

Prevention

When it happens

Trigger: Feeding a file that ends without closing the root element, e.g. `<root><child>` then EOF; a truncated stream where the closing tags were cut off; a lexer/fragment configuration that stops tokenizing before the document is complete.

Common situations: Truncated network reads or partial file writes (upload interrupted, log rotation mid-write); templating that conditionally skips closing tags; incremental streaming code that passes only the first chunk to the parser; version upgrades where a code path previously appended closing tags automatically.

Related errors


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