oven-sh/bun · error · TypeError

Cannot read private member from an object whose class did no

Error message

Cannot read private member from an object whose class did not declare it

What it means

The WeakMap-membership guard in the TypeScript __classPrivateFieldGet polyfill: for a field-backed private (state is a WeakMap), the receiver must already be registered (state.has(receiver)) — which happens only when the declaring class's constructor/field initializer ran for that object. Reading the private member from any object that did not initialize it throws this TypeError. It is the downlevel equivalent of native `#field` access on a non-instance, and in private.mjs it sits inside the polyfill used by the 'Polyfillprivate' bench.

Source

Thrown at bench/snippets/private.mjs:11

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() {

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Invoke methods on real instances of the declaring class (or bind them in the constructor: this.run = this.run.bind(this))
  2. Guard borrowed calls with an instanceof check before touching privates
  3. Prefer ES2022+ native #fields where possible — same error class, but surfaced directly by the engine

Example fix

// before
Foo.prototype.run.call(otherObj); // TypeError: otherObj never declared the field
// after
if (otherObj instanceof Foo) otherObj.run();
Defensive patterns

Strategy: type-guard

Validate before calling

// guard borrowed receivers before touching private members
if (!(this instanceof Foo)) throw new TypeError('method must be called on a Foo instance');

Type guard

function isFooInstance(receiver) {
  return receiver instanceof Foo;
}

Prevention

When it happens

Trigger: Calling a class method with a borrowed receiver, e.g. Foo.prototype.run.call(notAFoo), so `this` lacks an entry in the field's WeakMap; accessing a downleveled private field on a plain object; an instance created without running the declaring constructor.

Common situations: Detached methods / destructured-then-called class methods losing `this`; prototype borrowing; mixin patterns that copy methods onto unrelated objects; mocks in tests replacing instances.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/51151a1d1c8f8565. Report an issue: GitHub.