oven-sh/bun · error · Error
Missing output for ${id}
Error message
Missing output for ${id} What it means
While assembling the InternalModuleRegistryConstants.bin module-source blob, codegen walks layoutOrder(moduleList) and looks up each module id in the outputs map populated by the transpile loop. This error means a module listed before nativeStartIndex produced no bundled output — the registry list and the actually-bundled set have diverged. It is a codegen consistency invariant, so the generated blob is never written with a hole in it.
Source
Thrown at src/codegen/bundle-modules.ts:424
// Layout: [builtin functions combined source][\0][module 0][\n\0][module 1][\n\0]...
// WebCoreJSBuiltins.cpp's internalCombinedSource is the span at offset 0; the
// internal modules follow at known offsets.
//
// In debug builds the module sources are read from disk (BUN_DYNAMIC_JS_LOAD_PATH),
// so every module offset/length is 0. The functions span is still real in debug.
const moduleSpans: { enumName: string; offset: number; length: number }[] = [];
let blob: Buffer;
{
const chunks: Buffer[] = [Buffer.from(functionsSource + "\0", "latin1")];
let offset = chunks[0].length;
for (const id of layoutOrder(moduleList.slice(0, nativeStartIndex), outputs)) {
const enumName = idToEnumName(id);
if (debug) {
moduleSpans.push({ enumName, offset: 0, length: 0 });
continue;
}
const out = outputs.get(id.slice(0, -3).replaceAll("/", path.sep));
if (!out) throw new Error(`Missing output for ${id}`);
checkAscii(out);
// Trailing "\n\0": the NUL keeps each entry a valid C string should anything
// downstream ever strlen into the blob.
const bytes = Buffer.from(out + "\n\0", "latin1");
chunks.push(bytes);
moduleSpans.push({ enumName, offset, length: bytes.length - 1 });
offset += bytes.length;
}
blob = Buffer.concat(chunks);
}
writeIfNotChangedBinary(path.join(CODEGEN_DIR, "InternalModuleRegistryConstants.bin"), blob);
writeIfNotChanged(
path.join(CODEGEN_DIR, "InternalModuleRegistryConstants.S"),
`// Generated by src/codegen/bundle-modules.ts
#if defined(__APPLE__)
.section __TEXT,__constView on GitHub (pinned to 8c5296ac45)
Solutions
- Check the failing id from the message: confirm its entrypoint file exists under src/js and that the transpile loop actually processed it (look for it in the temp modules_out dir)
- If you added the module, verify it is inserted into moduleList at the correct position (JS modules must come before nativeStartIndex)
- On Windows, compare separators: the outputs key uses path.sep — make sure the id in moduleList uses '/' and the .slice(0,-3) suffix stripping matches the '.js' extension
- Diff bundle-modules.ts against main to find recent moduleList / nativeStartIndex edits
Defensive patterns
Strategy: validation
Validate before calling
// after the transpile loop, before blob assembly: every JS module id must have output
// (add inside bundle-modules.ts right before the blob block)
for (const id of moduleList.slice(0, nativeStartIndex)) {
const key = id.slice(0, -3).replaceAll("/", path.sep);
if (!outputs.has(key)) throw new Error(`Missing output for ${id}`);
} Prevention
- When registering a new builtin module, add both the source file and the moduleList entry in the same commit, positioned before nativeStartIndex
- Keep moduleList ids consistently '/'-separated with a .js suffix — the lookup key derives from that exact form
- Run the codegen step locally on Windows too if you touch moduleList; separator bugs only show there
When it happens
Trigger: Adding a new entry to moduleList in bundle-modules.ts whose entrypoint file does not exist or is not bundled; an id whose case or slash form does not match the outputs key (outputs keys use path.sep via replaceAll("/", path.sep), so separator/case mismatches on Windows miss); nativeStartIndex placed so a JS module is excluded from the transpile range but included in the blob range.
Common situations: Contributors registering a new builtin module (e.g. a new node: shim) and forgetting the source file or mis-ordering it relative to nativeStartIndex; Windows builds exposing separator normalization gaps between moduleList ids and outputs keys.
Related errors
- Builtin Bundler: do not use import.meta.require() (in ${file
- Errors in ${entrypoint}: ${errors.map(x => x[1]).join("\n")}
- Unknown wrap kind ${x.wrap_kind}
- non-ascii character in string "${str}". this will not be a v
- file did not exist after write: ${outputPath}
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/092356f21fc2186b.
Report an issue: GitHub.