{"record":{"id":"40dcfa64a9f41892","repo":"microsoft/TypeScript","slug":"private-method-is-not-writable","errorCode":null,"errorMessage":"Private method is not writable","messagePattern":"Private method is not writable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/compiler/factory/emitHelpers.ts","lineNumber":1350,"sourceCode":" *\r\n * Writing to a private static set accessor (when defined, TS 4.3+):\r\n *      __classPrivateFieldSet(<any>, <constructor>, <any>, \"a\", <function>)\r\n *\r\n * Writing to a private static set accessor (when not defined, TS 4.3+):\r\n *      __classPrivateFieldSet(<any>, <constructor>, <any>, \"a\", void 0)\r\n *      NOTE: This always results in a runtime error.\r\n *\r\n * Writing to a private static method (TS 4.3+):\r\n *      __classPrivateFieldSet(<any>, <constructor>, <any>, \"m\", <function>)\r\n *      NOTE: This always results in a runtime error.\r\n */\r\nconst classPrivateFieldSetHelper: UnscopedEmitHelper = {\r\n    name: \"typescript:classPrivateFieldSet\",\r\n    importName: \"__classPrivateFieldSet\",\r\n    scoped: false,\r\n    text: `\r\n            var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {\r\n                if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n                if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n                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\");\r\n                return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n            };`,\r\n};\r\n\r\n/**\r\n * Parameters:\r\n *  @param state — One of the following:\r\n *      - A WeakMap when the member is a private instance field.\r\n *      - A WeakSet when the member is a private instance method or accessor.\r\n *      - A function value that should be the undecorated class constructor when the member is a private static field, method, or accessor.\r\n *  @param receiver — The object being checked if it has the private member.\r\n *\r\n * Usage:\r\n * This helper is used to transform `#field in expression` to\r\n *      `__classPrivateFieldIn(<weakMap/weakSet/constructor>, expression)`\r\n */\r","sourceCodeStart":1332,"sourceCodeEnd":1368,"githubUrl":"https://github.com/microsoft/TypeScript/blob/b465fdbfe175304d9b977da137b2c178ae1091d3/src/compiler/factory/emitHelpers.ts#L1332-L1368","documentation":"Runtime TypeError from `__classPrivateFieldSet`. The helper throws immediately when `kind === \"m\"` (method): private methods are non-writable by design, so any assignment to one is rejected. Emitted for targets below ES2022; on native targets the same operation throws a different (spec-defined) TypeError.","triggerScenarios":"Assigning to a private method (`this.#m = fn`), in code compiled with the `__classPrivateFieldSet` helper. Reached both for instance and static private methods (`#m() {}` or `static #m() {}`).","commonSituations":"Attempting to swap/stub a private method for testing; refactor that confuses a private method with a private field; framework code that tries to monkey-patch methods on instances.","solutions":["Replace the private method with a private field holding a function if you genuinely need reassignment.","Refactor so behavior varies through a settable dependency rather than reassigning the method.","For tests, design seams (overridable protected methods, dependency injection) instead of patching privates.","Raise `target` to ES2022+ to get the spec error directly, which is clearer in stack traces."],"exampleFix":"// before\nclass C {\n  #m() { return 1; }\n  patch() { this.#m = () => 2; }  // runtime TypeError\n}\n// after\nclass C {\n  #m: () => number = () => 1;     // private field holding a function\n  patch() { this.#m = () => 2; }\n}","handlingStrategy":"validation","validationCode":"// Disallow assignment to private methods at design time; if reassignment is needed,\n// model the slot as a field-typed function (see exampleFix).","typeGuard":"type IsMethod<T> = T extends (...a: any[]) => any ? true : false;","tryCatchPattern":null,"preventionTips":["Treat private methods as immutable; use private function-valued fields when you need swapability.","Don't try to monkey-patch private methods for tests — inject the dependency instead."],"tags":["private-fields","runtime","downlevel","method","emit-helpers"],"backgroundTag":null,"analyzedSha":"b465fdbfe175304d9b977da137b2c178ae1091d3","analyzedAt":"2026-08-12T05:38:42.698Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}