oven-sh/bun · error · TypeError
Private method is not writable
Error message
Private method is not writable
What it means
The method guard in the TypeScript __classPrivateFieldSet polyfill: kind 'm' marks the private member as a method, and methods are never writable, so any attempted write throws immediately. It mirrors the native TypeError you get from `this.#method = fn`. In private.mjs the guard is part of the downlevel polyfill being benchmarked; the Foo class only uses kind 'f', so this fires only if something assigns to a private method.
Source
Thrown at bench/snippets/private.mjs:17
import { bench, run } from "../runner.mjs";
// This is a benchmark of the performance impact of using private properties.
bench("Polyfillprivate", () => {
"use strict";
var __classPrivateFieldGet =
(this && this.__classPrivateFieldGet) ||
function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet =
(this && this.__classPrivateFieldSet) ||
function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind === "a" ? f.call(receiver, value) : f ? (f.value = value) : state.set(receiver, value), value;
};
var _Foo_state, _Foo_inc;
class Foo {
constructor() {
_Foo_state.set(this, 1);
_Foo_inc.set(this, 13);
}
run() {
let n = 1000000;
while (n-- > 0) {
__classPrivateFieldSet(
this,
_Foo_state,
__classPrivateFieldGet(this, _Foo_state, "f") + __classPrivateFieldGet(this, _Foo_inc, "f"),View on GitHub (pinned to 8c5296ac45)
Solutions
- Remove the assignment to the private method — declare the behavior you need inside the class
- If the member must be replaceable, make it a private field holding a function (#handler = () => {}) instead of a method
- Add a dedicated setter method on the class that changes internal state instead of rewriting the method
Example fix
// before
class Foo {
#onDone() {}
reset() { this.#onDone = () => {}; } // TypeError: not writable
}
// after
class Foo {
#onDone = () => {};
reset() { this.#onDone = () => {}; }
} Defensive patterns
Strategy: try-catch
Try / catch
try {
this.#handler = fn; // illegal if #handler is a method
} catch (e) {
if (e instanceof TypeError && e.message.includes('Private method is not writable')) {
throw new TypeError('cannot replace private method; use a private field holding a function instead');
}
throw e;
} Prevention
- Model replaceable behavior as a private field holding a function (#handler = () => {}), never as a private method
- Search for assignments to #methods when refactoring fields into methods — the compiler catches native cases, downlevel code fails only at runtime
- Keep hot-path classes on ES2022+ output so invalid writes surface at compile time
When it happens
Trigger: Downleveled TypeScript executing `this.#method = someFunction` (generated as __classPrivateFieldSet(..., 'm')), or hand-calling the polyfill with kind 'm' — both are unconditional throws.
Common situations: Attempting to monkey-patch or swap behavior by overwriting a private method; refactoring a private field holding a function into a method without updating assignments; code ported from public-method patterns.
Related errors
- Private accessor was defined without a getter
- Private accessor was defined without a setter
- Cannot read private member from an object whose class did no
- bun-svelte-plugin: forceSide must be a string, got ${typeof
- bun-svelte-plugin: compilerOptions must be an object
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/619c6bd4a4294717.
Report an issue: GitHub.