oven-sh/bun · error · Error
NodeError can't fit ${count} codes in a u16
Error message
NodeError can't fit ${count} codes in a u16 What it means
generate-node-errors.ts counts every entry in the NodeErrors table plus all their sub-codes (the nested arrays from src/jsc/bindings/ErrorCode.ts) and checks the total fits in a u16, because the generated error-tag enum and its wire representation are 16-bit. If the table grows past 65,536 codes, codegen aborts rather than silently truncating tags. The comment at the throw site states the remedy: widen the generated enums.
Source
Thrown at src/codegen/generate-node-errors.ts:17
import path from "node:path";
import NodeErrors from "../jsc/bindings/ErrorCode.ts";
import { writeIfNotChanged } from "./helpers.ts";
const outputDir = process.argv[2];
if (!outputDir) {
throw new Error("Missing output directory");
}
const extra_count = NodeErrors.map(x => x.slice(3))
.filter(x => x.length > 0)
.reduce((ac, cv) => ac + cv.length, 0);
const count = NodeErrors.length + extra_count;
if (count > 1 << 16) {
// increase size of the enums below to have more tags
throw new Error(`NodeError can't fit ${count} codes in a u16`);
}
let enumHeader = ``;
let listHeader = ``;
let rustConsts = ``;
let rustAliases = ``;
let rustCodeStr = ``;
enumHeader = `
// clang-format off
// Generated by: src/codegen/generate-node-errors.ts
// Input: src/jsc/bindings/ErrorCode.ts
#pragma once
#include <cstdint>
namespace Bun {
static constexpr size_t NODE_ERROR_COUNT = ${count};View on GitHub (pinned to 8c5296ac45)
Solutions
- Confirm the count is legitimate (print NodeErrors.length + extra_count) and not an accident, e.g. an accidentally nested array multiplying sub-codes
- If genuine: widen the tag enum and every u16 field/argument that carries the tag in the generated headers and consumers (the throw-site comment instructs exactly this)
- Audit consumers of the generated tags (error construction, serialization) so the widened type propagates consistently
Defensive patterns
Strategy: validation
Validate before calling
// before regenerating, confirm the table still fits u16
import NodeErrors from "../jsc/bindings/ErrorCode.ts";
const extra = NodeErrors.map(x => x.slice(3)).filter(x => x.length > 0).reduce((a, c) => a + c.length, 0);
if (NodeErrors.length + extra > (1 << 16)) {
throw new Error("error table exceeds u16 — widen the generated enums first");
} Type guard
function errorCountFitsU16(entries: unknown[][]): boolean {
const total = entries.reduce((a, e) => a + 1 + Math.max(0, e.length - 3), 0);
return total <= (1 << 16);
} Prevention
- Bulk-import error codes with a script that checks the u16 budget before committing ErrorCode.ts
- Watch for accidentally nested arrays in the table — they multiply sub-code counts silently
When it happens
Trigger: Adding a large batch of Node error codes/sub-codes to src/jsc/bindings/ErrorCode.ts (or a script generating them) so the total exceeds 1 << 16; extremely unlikely from hand edits alone.
Common situations: Bulk-importing error codes from a new Node version or generating per-syscall/per-path error variants programmatically; essentially a theoretical guard for maintainers of the error table.
Related errors
- Missing output directory
- file did not exist after write: ${outputPath}
- Builtin Bundler: do not use import.meta.require() (in ${file
- Errors in ${entrypoint}: ${errors.map(x => x[1]).join("\n")}
- Missing output for ${id}
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/34ad2dca8f2821f3.
Report an issue: GitHub.