oven-sh/bun · error · Error
traced only ${order.length} functions, expected at least ${m
Error message
traced only ${order.length} functions, expected at least ${minFunctions} — the tracer or the symbol table is broken, and a near-empty order file silently costs the win What it means
Final sanity gate in generateOrderFile: after every workload, fewer than minFunctions (default MIN_FUNCTIONS) unique symbol names were collected. A near-empty order file would silently forfeit the link-order startup win, so the generator fails loudly instead of writing a useless artifact.
Source
Thrown at scripts/orderfile/generate.ts:328
let unresolved = 0;
for (const address of readTrace(out, workload.name)) {
const names = symbols.get(address);
if (!names) {
unresolved++;
continue;
}
for (const name of names) {
if (seen.has(name)) continue;
seen.add(name);
order.push(name);
}
}
const note = unresolved ? ` (${unresolved} unresolved)` : "";
log(` ${workload.name.padEnd(21)} +${order.length - before} functions${note}`);
}
if (order.length < minFunctions) {
throw new Error(
`traced only ${order.length} functions, expected at least ${minFunctions} — ` +
`the tracer or the symbol table is broken, and a near-empty order file silently costs the win`,
);
}
const header = [
`# ${darwin ? "ld -order_file" : "lld --symbol-ordering-file"}: functions bun executes while starting up,`,
"# in first-entry order, so they land together at the front of .text.",
"# Generated by scripts/orderfile/generate.ts — not committed.",
`# ${order.length} functions from ${workloads.length} workloads.`,
];
writeFileSync(outPath, header.join("\n") + "\n" + order.join("\n") + "\n");
return { count: order.length, outPath };
} finally {
rmSync(scratch, { recursive: true, force: true });
}
}
View on GitHub (pinned to 8c5296ac45)
Solutions
- Re-run with verbose enabled and read the per-workload counts — a large `(unresolved)` number means address/symbol mismatch
- Ensure the bun-profile passed to nm is byte-identical to the binary the workloads executed (rebuild once, then generate in one step)
- Confirm the tracer actually preloads in every workload (see error 172 diagnosis)
- Only if you intentionally traced a much smaller binary, lower minFunctions accordingly
Example fix
// before — silently accepts a near-empty order file
generateOrderFile({ buildDir });
// after — gate explicitly on a realistic floor
generateOrderFile({ buildDir, minFunctions: 10_000, verbose: true }); Defensive patterns
Strategy: try-catch
Validate before calling
import { spawnSync } from "node:child_process";
// Cheap coverage probe: how many text symbols can this nm even see for this binary?
const r = spawnSync(process.env.NM || "nm", [bunProfile]);
const visible = r.stdout.toString().split("\n").filter((l) => /^[0-9a-f]+ [tT] \S+$/.test(l)).length;
if (visible < minFunctions) throw new Error(`Symbol table only exposes ${visible} functions — minFunctions ${minFunctions} can never be met`); Try / catch
try {
return generateOrderFile({ buildDir, verbose: true });
} catch (err) {
if (/traced only \d+ functions/.test(String(err))) {
console.error("Order file would be near-empty — verify tracer preload and that nm read the exact binary that ran");
}
throw err;
} Prevention
- Always run generation with verbose:true when iterating; the per-workload `+N (X unresolved)` lines localize the breakage
- Generate the order file in the same CI step that built bun-profile so symbol table and traced binary cannot diverge
- Treat a sudden drop in traced-function counts as a real regression, never silence it by lowering minFunctions
When it happens
Trigger: Most traced addresses failing to resolve because the symbol table came from a different build than the binary executed; the tracer not loading in workloads (each trace would be empty or all-unresolved); a stripped or mismatched bun-profile. Watch the verbose per-workload `+N functions (X unresolved)` lines to see where resolution dies.
Common situations: Rebuilding the binary between generating the symbol table and running workloads; mixing binaries (default name vs custom exeName); tracer silently not preloading on hardened setups.
Related errors
- ${nm} failed on ${bunProfile} ${r.stderr}
- ${nm} reported no text symbols — is ${bunProfile} stripped?
- workload "${name}" wrote a truncated trace
- workload "${name}" wrote an invalid trace
- workload "${name}" recorded no entries — is the tracer loadi
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/c7815f50f09b148e.
Report an issue: GitHub.