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
- Add a getter paired with the setter: `get #x() { return this._v; }`.
- Move state into a plain private field `#x` and keep an accessor pair or expose reads via a normal method.
- 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
- Declare accessor pairs (`get #x` + `set #x`) together, or store state in a plain private field `#x` with explicit methods.
- Keep serialization/logging away from private accessors — expose a `snapshot()`/`toString()` method instead of reading internals.
- Review every private-accessor declaration for a matching counterpart as part of code review.
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
- "${name}" is read-only
- Decorating class property failed. Please ensure that proposa
- Non-computed member expression with property other than iden
- getter/setter property be compiled as CompiledProp::Accessor
- module string names unimplemented
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/682b922382ae1b06.
Report an issue: GitHub.