oven-sh/bun · error · Error

failed to build the tracer with ${cc} ${build.stderr}

Error message

failed to build the tracer with ${cc}
${build.stderr}

What it means

Compiling functrace.c into the injectable tracer (functrace.dylib on macOS, functrace.so on Linux) with $CC failed; the compiler's stderr is appended. The generator shells out to the ambient C toolchain instead of bundling a compiler, so a broken or missing toolchain surfaces here.

Source

Thrown at scripts/orderfile/generate.ts:209

  // The unstripped binary: its symbol table is what maps addresses back to names.
  const bunProfile = join(buildDir, options.exeName ?? "bun-profile");
  if (!existsSync(bunProfile)) {
    throw new Error(`${bunProfile} not found — build it first (bun run build:release)`);
  }

  const scratch = mkdtempSync(join(tmpdir(), "bun-orderfile-"));
  try {
    // ── Build the tracer and the pty runner ───────────────────────────────────
    const tracer = join(scratch, darwin ? "functrace.dylib" : "functrace.so");
    const ptyrun = join(scratch, "ptyrun");
    const cc = process.env.CC || "cc";
    const build = runCommand(
      darwin
        ? [cc, "-O2", "-dynamiclib", "-fPIC", "-o", tracer, join(here, "functrace.c")]
        : [cc, "-O2", "-shared", "-fPIC", "-o", tracer, join(here, "functrace.c"), "-ldl", "-lpthread"],
    );
    if (build.status !== 0) throw new Error(`failed to build the tracer with ${cc}\n${build.stderr}`);
    const pty = runCommand([cc, "-O2", "-o", ptyrun, join(here, "ptyrun.c"), ...(darwin ? [] : ["-lutil"])]);
    if (pty.status !== 0) throw new Error(`failed to build the pty runner with ${cc}\n${pty.stderr}`);

    // ── Symbol table and function starts ──────────────────────────────────────
    const symbols = readSymbolTable(bunProfile);
    const startsPath = join(scratch, "starts.bin");
    writeStarts(
      startsPath,
      [...symbols.keys()].sort((a, b) => a - b),
    );

    // ── Representative workloads ──────────────────────────────────────────────
    // Order matters: earlier workloads get the densest placement, so the plain
    // runtime startup path comes first.
    const fixtures = join(scratch, "fixtures");
    mkdirSync(join(fixtures, "tests"), { recursive: true });
    writeFileSync(
      join(fixtures, "hello.ts"),

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Read the appended stderr for the actual compile error
  2. Install a toolchain: `xcode-select --install` on macOS, `apt-get install build-essential` (or distro equivalent) on Linux
  3. Set CC to a working compiler (`CC=clang bun scripts/orderfile/generate.ts`)

Example fix

# before
$ bun scripts/orderfile/generate.ts
Error: failed to build the tracer with cc
clang: error: ... 

# after
$ xcode-select --install   # macOS
$ sudo apt-get install -y build-essential   # Linux
$ bun scripts/orderfile/generate.ts
Defensive patterns

Strategy: try-catch

Validate before calling

import { spawnSync } from "node:child_process";

const cc = process.env.CC || "cc";
if (spawnSync("which", [cc]).status !== 0) {
  throw new Error(`No C compiler (${cc}) — install Xcode CLT or build-essential before generating order files`);
}

Try / catch

try {
  buildTracer();
} catch (err) {
  if (/failed to build the tracer/.test(String(err))) {
    console.error("Tracer compile failed — check CC, install a toolchain, read the appended compiler stderr");
  }
  throw err;
}

Prevention

When it happens

Trigger: No cc on PATH and CC unset (fresh macOS without Xcode CLT, slim Linux without gcc); CC pointing at a wrapper or incompatible compiler; missing C headers/SDK for the -dynamiclib/-shared build.

Common situations: Fresh dev machines; minimal CI containers; CC leftovers like a cross-compiler default from another project's env.

Related errors


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