next build crashes on Node 24.15+ and 25.7+ under Yarn PnP: require.extensions undefined in next-config-ts/require-hook.js
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
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.ymlhas defaultnodeLinker(pnp) — i.e. don't setnodeLinker: 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
- Breaks in CI on Bitbucket Pipelines using the
node:24-slimimage as soon as Bitbucket's cache refreshes to the 24.15.0 layer. - Workaround for users: pin
node:24.14.1-slim(or any Node < 24.15), or switch off Yarn PnP. - Node issue: https://github.com/nodejs/node/issues/62786
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/next/src/build/next-config-ts/require-hook.ts, then inspect its eager import from transpile-config.js. Run the linked Yarn PnP reproducer with Node 24.15+ and verify that next build completes and produces the .next/ output without breaking working Node versions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, next.js, node.js, typescript
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100