{"record":{"id":"6201e9b7be991f50","repo":"oven-sh/bun","slug":"could-not-find-bun-foreach-esm-and-cjs-native-modu","errorCode":null,"errorMessage":"Could not find BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE in NativeModuleList.h. Knowing native module IDs is a part of the codegen process.","messagePattern":"Could not find BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE in NativeModuleList\\.h\\. Knowing native module IDs is a part of the codegen process\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/codegen/internal-module-registry-scanner.ts","lineNumber":56,"sourceCode":"  const nativeModuleH = fs.readFileSync(path.join(basedir, \"../jsc/modules/NativeModuleList.h\"), \"utf8\");\n  for (const [_, idString, enumValue] of nativeModuleH.matchAll(/macro\\((.*?),(.*?)\\)/g)) {\n    const processedIdString = JSON.parse(idString.trim().replace(/_s$/, \"\"));\n    const processedEnumValue = enumValue.trim();\n    const processedNumericId = nextNativeModuleId++;\n    nativeModuleIds[processedIdString] = processedNumericId;\n    nativeModuleEnums[processedIdString] = processedEnumValue;\n    nativeModuleEnumToId[processedEnumValue] = processedNumericId;\n  }\n\n  const nativeStartIndex = moduleList.length;\n\n  for (const [id] of Object.entries(nativeModuleIds)) {\n    moduleList.push(id);\n    internalRegistry.set(id, moduleList.length - 1);\n  }\n\n  if (nextNativeModuleId === 0) {\n    throw new Error(\n      \"Could not find BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE in NativeModuleList.h. Knowing native module IDs is a part of the codegen process.\",\n    );\n  }\n\n  function codegenRequireId(id: string) {\n    return `(__intrinsic__getInternalField(__intrinsic__internalModuleRegistry, ${id}) || __intrinsic__createInternalModuleById(${id}))`;\n  }\n\n  const requireTransformer = (specifier: string, from: string) => {\n    const directMatch = internalRegistry.get(specifier);\n    if (directMatch) return codegenRequireId(`${directMatch}/*${specifier}*/`);\n\n    const relativeMatch =\n      resolveSyncOrNull(specifier, path.join(basedir, path.dirname(from))) ?? resolveSyncOrNull(specifier, basedir);\n\n    const suffix =\n      'Only files in \"src/js\" besides \"src/js/builtins\" can be imported here. Note that the \"node:\" or \"bun:\" prefix is required here.';\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/codegen/internal-module-registry-scanner.ts#L38-L74","documentation":"internal-module-registry-scanner.ts reads src/jsc/modules/NativeModuleList.h and parses every `macro(\"id\", Enum)` entry inside BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE to assign native module IDs used throughout codegen. If zero entries matched (nextNativeModuleId === 0), the header was moved, renamed, or reformatted, and codegen cannot proceed without those IDs.","triggerScenarios":"The file src/jsc/modules/NativeModuleList.h is missing, the macro BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE was renamed, or the entries no longer match the /macro\\((.*?),(.*?)\\)/ pattern (e.g. changed to macro(id, Enum) without string quotes or a different helper name).","commonSituations":"Reformatting or restructuring the JSC module list header; moving it into another directory during a refactor; a bad merge that dropped the #define block.","solutions":["Restore src/jsc/modules/NativeModuleList.h at that exact path with the `#define BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE(macro)` block.","Keep entries in the `macro(\"fs\", Fs)` shape — string literal ID first, enum identifier second — so the scanner regex matches.","If the header must move, update the path in internal-module-registry-scanner.ts (line 38) in the same commit."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const headerPath = path.join(basedir, \"../jsc/modules/NativeModuleList.h\");\nconst header = fs.readFileSync(headerPath, \"utf8\");\nif (!/macro\\((.*?),(.*?)\\)/.test(header)) {\n  throw new Error(`${headerPath}: no macro(id, Enum) entries found — header was moved or reformatted`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat NativeModuleList.h's macro name and file location as a codegen contract: change scanner and header together.","Add a CI check that codegen output is unchanged after reformatting PRs (catches marker-destroying rustfmt/clang-format changes).","Do not reformat or rename inside the BUN_FOREACH_ESM_AND_CJS_NATIVE_MODULE block."],"tags":["codegen","native-modules","header","codegen-scanner"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}