swc-project/swc · error · TypeError

"${name}" is write-only

Error message

"${name}" is write-only

What it means

The ES2022 private-field transform emits `_write_only_error("#x")` (crates/swc_ecma_compat_es2022/src/class_properties/private_field.rs:728) when compiled code reads a private accessor that declares only a setter. At runtime the helper throws `TypeError: "#x" is write-only`, mirroring the engine error for reading a set-only private accessor.

Source

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

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

use super::{HelperDef, HelperName};

pub const DEF: HelperDef = HelperDef {
    name: HelperName::write_only_error,
    local: "_write_only_error",
    import_path: "@swc/helpers/_/_write_only_error",
    #[cfg(feature = "inline-helpers")]
    source: r#"function _write_only_error(name) {
    throw new TypeError("\"" + name + "\" is write-only");
}
"#,
    #[cfg(feature = "inline-helpers")]
    deps: super::HelperBitmap::from_bits(0x00000200000000000000000000000000),
};

#[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. Add a getter paired with the setter: `get #x() { return this._v; }`.
  2. Move state into a plain private field `#x` and keep an accessor pair or expose reads via a normal method.
  3. Remove the read; if the value is write-only by design, return the assigned value from the API instead.

Example fix

// before
class Socket {
  set #buf(v) { this._buf = Buffer.from(v); }
  flush() { console.log(this.#buf); } // TypeError: "#buf" is write-only
}

// after
class Socket {
  #buf;
  set buf(v) { this.#buf = Buffer.from(v); }
  flush() { console.log(this.#buf); }
}
Defensive patterns

Strategy: try-catch

Try / catch

// Setter-only private accessors cannot be probed, so guard the read site.
try {
  debug(this.#buf);
} catch (err) {
  if (err instanceof TypeError && /is write-only/.test(err.message)) {
    debug(this.readBuf()); // use the read API instead
  } else throw err;
}

Prevention

When it happens

Trigger: `class A { set #x(v) { this._v = v; } read() { return this.#x; } }` — any read of a setter-only private accessor (`this.#x` in an expression, template literal, or log) in downleveled output.

Common situations: Write-only private setters used for validation with an accidental read added later (logging, debug serialization); refactors that move reads into the class without adding a getter; code generators that reference every declared private name.

Related errors


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