Link to the code that reproduces this issue
https://github.com/kabo/node-24.15-require-extensions-repro
To Reproduce
yarn create next-app@16.2.4 repro (any Next 16 project).
yarn set version 4.14.1
- Ensure
.yarnrc.yml has default nodeLinker (pnp) — i.e. don't set nodeLinker: node-modules.
- Run with Node 24.15.0:
yarn build.
- Observes the stack trace below.
Current vs. Expected behavior
Expected: next build compiles and produces the .next/ output.
Actual: build exits with
file:///opt/atlassian/pipelines/agent/build/.yarn/__virtual__/next-virtual-51f158077e/6/root/.yarn/berry/cache/next-npm-16.2.4-a755a7c7e3-10.zip/node_modules/next/dist/build/next-config-ts/require-hook.js:35
const oldJSHook = require.extensions['.js'];
^
TypeError: Cannot read properties of undefined (reading '.js')
at Object.<anonymous> (file:///.../next/dist/build/next-config-ts/require-hook.js:35:37)
at loadCJSModule (node:internal/modules/esm/translators:185:3)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:231:7)
at ModuleJob.runSync (node:internal/modules/esm/module_job:404:39)
at require (node:internal/modules/esm/translators:145:9)
at Object.<anonymous> (file:///.../next/dist/build/next-config-ts/transpile-config.js:15:22)
at loadCJSModule (node:internal/modules/esm/translators:185:3)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:231:7)
at ModuleJob.runSync (node:internal/modules/esm/module_job:404:39)
at require (node:internal/modules/esm/translators:145:9)
Node.js v24.15.0
Crash happens regardless of whether the project uses next.config.ts or next.config.mjs, because transpile-config.js imports require-hook.js eagerly at top level.
Root cause (upstream)
This is a regression in Node.js v24.15.0: the require function passed to CJS modules loaded via the ESM loader no longer has .extensions defined when the module source comes through a custom loader (Yarn PnP's zip loader). Verified with a ~10-line reproducer independent of Next.js. See filed issue: <nodejs/node_issue_link_goes_here>.
Likely introduced by nodejs/node#61769 (ESM loader cycle reduction), which also caused nodejs/node#62012 (EBADF fstat on zip fds in the same subsystem).
Requested fix
Even though this is upstream-caused, Next.js reaches for a deprecated API (require.extensions, DEP0007 since 2014) at module top level. One-line defensive access would un-break every Yarn PnP user on Node 24.15+ today, without waiting on a Node patch release:
--- a/packages/next/src/build/next-config-ts/require-hook.ts
+++ b/packages/next/src/build/next-config-ts/require-hook.ts
-const oldJSHook = require.extensions['.js'];
+const oldJSHook = require.extensions?.['.js'];
@@
- for (const ext of extensions){
- const oldHook = require.extensions[ext] ?? oldJSHook;
- require.extensions[ext] = function(mod, oldFilename) {
+ for (const ext of extensions){
+ const oldHook = require.extensions?.[ext] ?? oldJSHook;
+ if (!require.extensions) break;
+ require.extensions[ext] = function(mod, oldFilename) {
(Other accesses in the same file would need similar guards, or the whole registerHook function should early-return when require.extensions is falsy.)
No behavior change on working Node versions, since require.extensions has always been defined there.
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT_DYNAMIC Mon, 30 Mar 2026 19:15:57 +0000
Available memory (MB): 31932
Available CPU cores: 20
Binaries:
Node: 24.14.1
npm: 11.11.0
Yarn: 4.14.1
pnpm: N/A
Relevant Packages:
next: 16.2.4
eslint-config-next: N/A
react: 19.2.5
react-dom: 19.2.5
typescript: 6.0.3
Next.js Config:
output: export
Which area(s) are affected? (Select all that apply)
Module Resolution
Which stage(s) are affected? (Select all that apply)
next build (local)
Additional context
Link to the code that reproduces this issue
https://github.com/kabo/node-24.15-require-extensions-repro
To Reproduce
yarn create next-app@16.2.4 repro(any Next 16 project).yarn set version 4.14.1.yarnrc.ymlhas defaultnodeLinker(pnp) — i.e. don't setnodeLinker: node-modules.yarn build.Current vs. Expected behavior
Expected:
next buildcompiles and produces the.next/output.Actual: build exits with
Crash happens regardless of whether the project uses
next.config.tsornext.config.mjs, becausetranspile-config.jsimportsrequire-hook.jseagerly at top level.Root cause (upstream)
This is a regression in Node.js v24.15.0: the
requirefunction passed to CJS modules loaded via the ESM loader no longer has.extensionsdefined when the module source comes through a custom loader (Yarn PnP's zip loader). Verified with a ~10-line reproducer independent of Next.js. See filed issue: <nodejs/node_issue_link_goes_here>.Likely introduced by nodejs/node#61769 (ESM loader cycle reduction), which also caused nodejs/node#62012 (EBADF fstat on zip fds in the same subsystem).
Requested fix
Even though this is upstream-caused, Next.js reaches for a deprecated API (
require.extensions, DEP0007 since 2014) at module top level. One-line defensive access would un-break every Yarn PnP user on Node 24.15+ today, without waiting on a Node patch release:(Other accesses in the same file would need similar guards, or the whole
registerHookfunction should early-return whenrequire.extensionsis falsy.)No behavior change on working Node versions, since
require.extensionshas always been defined there.Provide environment information
Which area(s) are affected? (Select all that apply)
Module Resolution
Which stage(s) are affected? (Select all that apply)
next build (local)
Additional context
node:24-slimimage as soon as Bitbucket's cache refreshes to the 24.15.0 layer.node:24.14.1-slim(or any Node < 24.15), or switch off Yarn PnP.