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

  1. Confirm the count is legitimate (print NodeErrors.length + extra_count) and not an accident, e.g. an accidentally nested array multiplying sub-codes
  2. 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)
  3. 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

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


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