oven-sh/bun · error · Error

${typeName}.${name}: `this: true` accessors require `sharedT

Error message

${typeName}.${name}: `this: true` accessors require `sharedThis: true`

What it means

generate-classes.ts supports `this: true` on proto accessors so a getter/setter receives the JS `this` value as an extra argument — but the generated thunk that forwards this_value only exists on the sharedThis code path (host_fn::host_fn_getter_this_shared). If a class definition opts out with `sharedThis: false` while a proto getter/setter uses `this: true`, the required thunk cannot be generated, so the generator rejects the combination. Note the generator default is sharedThis: true; this fires only on an explicit opt-out.

Source

Thrown at src/codegen/generate-classes.ts:2000

    thunk(
      classSymbolName(typeName, "call"),
      `(global: &JSGlobalObject, callframe: &CallFrame) -> JSValue`,
      `    host_fn::host_fn_static(global, callframe, ${T}::call)`,
    );
  }

  // ── proto getters / setters / fns ────────────────────────────────────────
  // Closure form (`|t, g, c| T::method(t, g, c)`) rather than bare `T::method`
  // so `&mut T → &T` autoref/coercion applies — many user impls take `&self`.
  {
    const seen = new Map<string, string>();
    const exportNames = name => zigExportName(seen, n => protoSymbolName(typeName, n), proto[name]);
    for (const name in proto) {
      const { getter, setter, fn, this: thisValue = false, passThis, DOMJIT } = proto[name];
      const names = exportNames(name);

      if (thisValue && !sharedThis && (names.getter || names.setter)) {
        throw new Error(`${typeName}.${name}: \`this: true\` accessors require \`sharedThis: true\``);
      }

      if (names.getter) {
        const id = rustSnakeIdent(getter);
        thunk(
          names.getter,
          `(this: ${recv}, ${thisValue ? "this_value: JSValue, " : ""}global: &JSGlobalObject) -> JSValue`,
          thisValue
            ? `    host_fn::host_fn_getter_this_shared(this, this_value, global, |t, v, g| ${T}::${id}(t, v, g))`
            : `    ${helper("host_fn_getter")}(this, global, |t, g| ${T}::${id}(t, g))`,
        );
      }

      if (names.setter) {
        const id = rustSnakeIdent(setter);
        thunk(
          names.setter,
          `(this: ${recv}, ${thisValue ? "this_value: JSValue, " : ""}global: &JSGlobalObject, value: JSValue) -> bool`,

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Remove the explicit `sharedThis: false` from the class definition so it uses the default shared this-handling the accessor requires
  2. Or drop `this: true` from the getter/setter if the accessor does not actually need the JS receiver
  3. Re-run codegen and confirm the generated host_fn_getter_this_shared thunk compiles

Example fix

// before (Foo.classes.ts)
export default {
  sharedThis: false,
  proto: { get owner() { /* this: true */ } },
} as ClassDefinition<Foo>;

// after
export default {
  proto: { get owner() { /* this: true */ } },
} as ClassDefinition<Foo>;
Defensive patterns

Strategy: validation

Validate before calling

// check the combo before codegen: this:true accessors need sharedThis
const sharedThis = obj.sharedThis !== false; // generator default is true
for (const [name, prop] of Object.entries(obj.proto ?? {})) {
  const p = prop as { this?: boolean; getter?: unknown; setter?: unknown };
  if (p.this === true && !sharedThis && (p.getter || p.setter)) {
    throw new Error(`${obj.name}.${name}: this:true accessor requires sharedThis`);
  }
}

Prevention

When it happens

Trigger: Writing `const config = { sharedThis: false, proto: { get foo() { ... } } }` style definitions in a .classes.ts file — i.e. any proto getter/setter entry with `this: true` on a class whose definition explicitly sets `sharedThis: false`.

Common situations: Adding `this: true` to an accessor of an older class that predates the sharedThis default and carries an explicit `sharedThis: false`; migrating a mutable-self class to shared accessors without removing the opt-out.

Related errors


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