Skip to content

[BUG] HAS_BROKEN_FSTAT_FOR_ZIP_FDS version gate should include Node 22.22+ #7140

Description

@danieltroger

What's the problem?

The fstat workaround added in #7070 and widened in #7104 still misses the v22 LTS line:

// .pnp.loader.mjs (Yarn 4.14.1)
const HAS_BROKEN_FSTAT_FOR_ZIP_FDS = major > 25 || (major === 25 && minor >= 7) || (major === 24 && minor >= 15);

The same family of ESM/module loader changes by Joyee Cheung (originals being nodejs/node#61769) was backported to Node v22.22.3 (released 2026-05-13), reproducing the identical EBADF: bad file descriptor, fstat.

Per nodejs/node#62012, v22.22.2 was reported as still working, so the regression hits at v22.22.3.

Relevant module/esm commits in v22.22.2...v22.22.3:

1769d74 esm: populate separate cache for require(esm) in imported CJS (Joyee Cheung)
12a2462 module: only put directly require-d ESM into require.cache (Joyee Cheung)
39147c1 module: use sync cjs when importing cts (Marco Ippolito)
2e91b28 module: handle null source from async loader hooks in sync hooks (Joyee Cheung)
9a2e213 module: do not wrap module._load when tracing is not enabled (Joyee Cheung)
5065a0a module: do not invoke resolve hooks twice for imported cjs (Joyee Cheung)

Especially nodejs/node#59929

Reproduction

$ node --version
v22.22.3

$ yarn --version
4.14.1

$ yarn run sql-ts  # any CJS bin served from .yarn/cache zip

node:internal/modules/run_main:123
    triggerUncaughtException(
    ^
Error: EBADF: bad file descriptor, fstat
    at tryStatSync (node:fs:390:25)
    at readFileSync (node:fs:446:17)
    at getSourceSync (node:internal/modules/esm/load:41:14)
    at defaultLoad (node:internal/modules/esm/load:92:34)
    at nextLoad (node:internal/modules/esm/hooks:748:28)
    at load$1 (file:///.../.pnp.loader.mjs:1526:12)
    at nextLoad (node:internal/modules/esm/hooks:748:28)
    at Hooks.load (node:internal/modules/esm/hooks:385:26)
    at handleMessage (node:internal/modules/esm/worker:199:24)
    at checkForMessages (node:internal/modules/esm/worker:141:28) {
  errno: -9,
  code: 'EBADF',
  syscall: 'fstat'
}

Node.js v22.22.3

Works on Node v22.22.2 (per nodejs/node#62012), fails on v22.22.3.

Suggested fix

Widen the gate in packages/yarnpkg-pnp/sources/esm-loader/loaderFlags.ts:

export const HAS_BROKEN_FSTAT_FOR_ZIP_FDS =
  major > 25 ||
  (major === 25 && minor >= 7) ||
  (major === 24 && minor >= 15) ||
  (major === 22 && minor >= 22);

Strictly the regression starts at v22.22.3, but the existing gate is major.minor only, so (major === 22 && minor >= 22) over-covers v22.22.0..v22.22.2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions