oven-sh/bun · error · Error

"builtin" should be string

Error message

"builtin" should be string

What it means

In Bun's class-bindings generator (src/codegen/generate-classes.ts), a property in a *.classes.ts definition that sets the `builtin` key must give a string naming a JSC builtin generator function — the value is emitted verbatim into a HashTableValue BuiltinGeneratorType row. This error fires when `builtin` is present but has any other type (boolean, number, object), which would generate invalid C++.

Source

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

      setter = symbol + "SetterWrap";
    }
    if (fn) {
      fn = symbol + "Callback";
    }
  } else {
    if (getter) {
      getter = symbolName(typeName, getter);
    }
    if (setter || writable) {
      setter = symbolName(typeName, setter);
    }
    if (fn) {
      fn = symbolName(typeName, fn);
    }
  }

  if (builtin !== undefined) {
    if (typeof builtin !== "string") throw new Error('"builtin" should be string');
    return `
{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, ${builtin}, ${
      length || 0
    } } }
`.trim();
  } else if (fn !== undefined) {
    if (DOMJIT) {
      // { "getElementById"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsTestDOMJITPrototypeFunction_getElementById, &DOMJITSignatureForTestDOMJITGetElementById } },
      return `
      { "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::DOMJITFunctionType, ${fn}, &DOMJITSignatureFor${symbol} } }
      `.trim();
    }
    return `
{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::NativeFunctionType, ${fn}, ${
      length || 0
    } } }
`.trim();
  } else if (getter && setter) {

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Open the .classes.ts file for the class named in your build log and find the property with a non-string `builtin` value
  2. Either set it to a string naming the intended JSC builtin generator, or delete `builtin` and declare the member properly with `fn`/`getter`
  3. Re-run codegen to confirm the generated HashTable values compile

Example fix

// before (Foo.classes.ts)
proto: {
  toArray: { builtin: true },
}

// after
proto: {
  toArray: { fn: "toArray", length: 0 },
}
Defensive patterns

Strategy: validation

Validate before calling

// lint .classes.ts definitions: `builtin` must be a string
for (const [name, prop] of Object.entries({ ...obj.klass, ...obj.proto })) {
  const p = prop as Record<string, unknown>;
  if ("builtin" in p && typeof p.builtin !== "string") {
    throw new Error(`${obj.name}.${name}: "builtin" should be string`);
  }
}

Type guard

// narrow a class-definition property before use
function isBuiltinProp(p: { builtin?: unknown }): p is { builtin: string } {
  return "builtin" in p && typeof p.builtin === "string";
}

Prevention

When it happens

Trigger: Writing a class definition like `proto: { foo: { builtin: true } }` or `builtin: 1` in a file under src/ ending in .classes.ts, then running codegen (`bun run build`).

Common situations: Contributors assuming `builtin: true` is a boolean feature flag; copy-paste typos from neighboring fn/getter entries; refactors that move a string constant into a variable of the wrong type.

Related errors


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