oven-sh/bun · error · Error

workload "${name}" wrote a truncated trace

Error message

workload "${name}" wrote a truncated trace

What it means

readTrace found the workload's trace file smaller than its fixed binary header (TRACE_HEADER_WORDS × 8 bytes), meaning functrace.c died or was killed before it could even finish writing the header. The workload name identifies which run produced the bad file.

Source

Thrown at scripts/orderfile/generate.ts:170

  if (symbols.size === 0) throw new Error(`${nm} reported no text symbols — is ${bunProfile} stripped?`);
  return symbols;
}

/** Write function starts for functrace.c: u64 magic, version, count, addresses. */
function writeStarts(path: string, addresses: number[]): void {
  const buffer = new ArrayBuffer((STARTS_HEADER_WORDS + addresses.length) * 8);
  const words = new BigUint64Array(buffer);
  words[0] = STARTS_MAGIC;
  words[1] = 1n;
  words[2] = BigInt(addresses.length);
  for (let i = 0; i < addresses.length; i++) words[STARTS_HEADER_WORDS + i] = BigInt(addresses[i]!);
  writeFileSync(path, new Uint8Array(buffer));
}

/** Read a trace functrace.c wrote: first-entry addresses, slide already removed. */
function readTrace(path: string, name: string): number[] {
  const raw = readFileSync(path);
  if (raw.byteLength < TRACE_HEADER_WORDS * 8) throw new Error(`workload "${name}" wrote a truncated trace`);
  const header = new BigUint64Array(raw.buffer, raw.byteOffset, TRACE_HEADER_WORDS);
  if (header[0] !== TRACE_MAGIC || header[1] !== 1n) throw new Error(`workload "${name}" wrote an invalid trace`);
  const count = Number(header[4]);
  if (count === 0) throw new Error(`workload "${name}" recorded no entries — is the tracer loading?`);
  const body = new BigUint64Array(raw.buffer, raw.byteOffset + TRACE_HEADER_WORDS * 8, count);
  const out: number[] = new Array(count);
  for (let i = 0; i < count; i++) out[i] = Number(body[i]);
  return out;
}

export function generateOrderFile(options: GenerateOptions): { count: number; outPath: string } {
  const buildDir = resolve(options.buildDir);
  const outPath = resolve(options.outPath ?? join(buildDir, "linker.order"));
  const minFunctions = options.minFunctions ?? MIN_FUNCTIONS;
  const log = (message: string) => options.verbose && console.log(message);

  const darwin = process.platform === "darwin";
  if (process.platform !== "linux" && !(darwin && process.arch === "arm64")) {

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Re-run the generator — it creates a fresh scratch dir and rebuilds the tracer
  2. Check disk space and permissions on the temp directory used for trace output
  3. Run the failing workload manually with BUN_FUNCTRACE_STARTS/BUN_FUNCTRACE_OUT set to observe the tracer crash
  4. Confirm the tracer was compiled for the same arch as bun-profile
Defensive patterns

Strategy: try-catch

Validate before calling

import { statSync, unlinkSync } from "node:fs";

// Clear stale/partial traces before the run so readTrace only sees fresh files.
for (const f of workloads) {
  try {
    if (statSync(f.out).size < TRACE_HEADER_WORDS * 8) unlinkSync(f.out);
  } catch {}
}

Try / catch

try {
  order.push(...readTrace(out, workload.name));
} catch (err) {
  if (/truncated trace/.test(String(err))) {
    console.error(`Tracer died writing ${out} — check disk space and tracer arch; rerunning recreates scratch`);
  }
  throw err;
}

Prevention

When it happens

Trigger: The tracer crashed on load or early in the run; the workload process was killed (timeout/OOM) mid-write; the out path (BUN_FUNCTRACE_OUT) sits on a full or read-only filesystem so the file was only partially created.

Common situations: Tracer/binary arch mismatch causing an immediate crash; scratch tmpdir filling up in CI; workloads killed by resource limits.

Related errors


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