oven-sh/bun · error · AggregateError

Failed to generate classes

Error message

Failed to generate classes

What it means

The class generator collects every failure encountered while importing/parsing the *.classes.ts files into an array and throws them all at once wrapped in an AggregateError. 'Failed to generate classes' is therefore an umbrella: the real diagnostics are the individual errors inside `errors` (accessed via `error.errors`), each typically a syntax error, missing import, or runtime exception in one of the definition files.

Source

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

      );
      continue;
    }

    console.log("Found", result.default.length, "classes from", file);
    for (let { name, proto = {}, klass = {} } of result.default) {
      let protoProps = Object.keys(proto).length ? `${Object.keys(proto).length} fields` : "";
      let klassProps = Object.keys(klass).length ? `${Object.keys(klass).length} class fields` : "";
      let props = [protoProps, klassProps].filter(Boolean).join(", ");
      if (props.length) props = ` (${props})`;
      console.log(`  - ${name}` + props);
    }

    for (const def of result.default) def._classesFilePath = filepath;
    classes.push(...result.default);
  }

  if (errors.length) {
    throw new AggregateError(errors, "Failed to generate classes");
  }
}
classes.sort((a, b) => (a.name < b.name ? -1 : 1));

// sort all the prototype keys and klass keys
for (const obj of classes) {
  let { klass = {}, proto = {} } = obj;

  klass = Object.fromEntries(Object.entries(klass).sort(([a], [b]) => a.localeCompare(b)));
  proto = Object.fromEntries(Object.entries(proto).sort(([a], [b]) => a.localeCompare(b)));

  obj.klass = klass;
  obj.proto = proto;
}

const GENERATED_CLASSES_FOOTER = `

typedef SYSV_ABI void (*CppStructuredCloneableSerializeFunction)(CloneSerializer*, const uint8_t*, uint32_t);

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Inspect the aggregated causes — the message itself is generic; run with the AggregateError printed (e.g. `catch (e) { console.error(e.errors ?? e) }` or look at the build log lines above) to see each file's real error
  2. Fix the first per-file error (usually a syntax/import problem in the named .classes.ts) and re-run; later errors often cascade from the first
  3. If a file was recently added, verify it has a default export shaped like other .classes.ts files

Example fix

// reading the real causes when wrapping the codegen step
try {
  await import("./generate-classes.ts");
} catch (e) {
  if (e instanceof AggregateError) for (const inner of e.errors) console.error(inner);
  else throw e;
}
Defensive patterns

Strategy: try-catch

Type guard

function isAggregateOfClassErrors(e: unknown): e is AggregateError {
  return e instanceof AggregateError && Array.isArray(e.errors) && e.message === "Failed to generate classes";
}

Try / catch

try {
  await generate();
} catch (e) {
  if (isAggregateOfClassErrors(e)) {
    for (const cause of e.errors) console.error(cause); // real per-file diagnostics
    process.exitCode = 1;
  } else throw e;
}

Prevention

When it happens

Trigger: Any exception while a .classes.ts module is imported: TypeScript/JS syntax errors, importing a symbol that no longer exists, a top-level expression throwing (e.g. calling a helper with undefined), or a file whose default export is not a valid class definition object.

Common situations: Mid-refactor builds after renaming a type or moving a file referenced by class definitions; merge conflicts inside .classes.ts files leaving invalid syntax.

Related errors


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