yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.43k stars 1.11k forks source link

[Bug?]: `fsBinding.cpSyncCheckPaths` error in Node 22 #6488

Open markandrus opened 1 month ago

markandrus commented 1 month ago

Self-service

Describe the bug

I have a monorepo with a build script that calls fs.cpSync to copy Yarn-installed dependencies into a build directory. When using Yarn and Node 20, it works fine. When using Yarn and Node 22, it fails with

Copying /private/tmp/test/.yarn/cache/semver-npm-7.6.3-57e82c14d5-88f33e148b.zip/node_modules/semver/package.json to semver.json...
node:internal/fs/cp/cp-sync:56
  fsBinding.cpSyncCheckPaths(src, dest, opts.dereference, opts.recursive);
            ^

Error: Unknown system error 17: Unknown system error 17, lstat '/private/tmp/test/.yarn/cache/semver-npm-7.6.3-57e82c14d5-88f33e148b.zip/node_modules/semver/package.json'
    at cpSyncFn (node:internal/fs/cp/cp-sync:56:13)
    at Object.cpSync (node:fs:3044:3)
    at Object.<anonymous> (/private/tmp/test/packages/foo/index.cjs:7:4)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at require$$0.Module._extensions..js (/private/tmp/test/.pnp.cjs:5699:33)
    at Module.load (node:internal/modules/cjs/loader:1317:32)
    at Module._load (node:internal/modules/cjs/loader:1127:12)
    at require$$0.Module._load (/private/tmp/test/.pnp.cjs:5547:31)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14) {
  errno: 17,
  code: 'Unknown system error 17',
  syscall: 'lstat',
  path: '/private/tmp/test/.yarn/cache/semver-npm-7.6.3-57e82c14d5-88f33e148b.zip/node_modules/semver/package.json'
}

Node.js v22.6.0

To reproduce

You can use the following script to reproduce. For example,

nvm use 20
sh repro.sh

should succeed, while

nvm use 22
sh repro.sh

should fail. Here is the script, repro.sh:

set -ex

cat >package.json <<EOF
{
  "name": "test",
  "packageManager": "yarn@4.4.1",
  "workspaces": [
    "packages/*"
  ]
}
EOF

mkdir -p packages/foo

cat >packages/foo/package.json <<EOF
{
  "name": "foo",
  "version": "1.0.0",
  "main": "index.cjs",
  "dependencies": {
    "semver": "*"
  }
}
EOF

cat >packages/foo/index.cjs <<EOF
const fs = require('fs')
const path = require('path')

const src = path.join(require.resolve('semver'), '..', 'package.json')
const dst = path.join('.', 'semver.json')
console.log(\`Copying \${src} to \${dst}...\`)
fs.cpSync(src, dst)
EOF

yarn install

yarn workspace foo exec node ./index.cjs

Environment

System:
    OS: macOS 14.5
    CPU: (8) arm64 Apple M2
  Binaries:
    Node: 22.6.0 - /private/var/folders/z5/r01rjpb57_d5ggd6zg8q7dg00000gp/T/xfs-69bfefa1/node
    Yarn: 4.4.1 - /private/var/folders/z5/r01rjpb57_d5ggd6zg8q7dg00000gp/T/xfs-69bfefa1/yarn
    npm: 10.8.2 - ~/.nvm/versions/node/v22.6.0/bin/npm

Additional context

No response

markandrus commented 1 month ago

I can workaround this by using cp from fs/promises 👍

It looks like https://github.com/nodejs/node/pull/53614 introduces cpSyncCheckPaths, and perhaps this needs patching in @yarnpkg/fslib?