berry icon indicating copy to clipboard operation
berry copied to clipboard

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

Open markandrus opened this issue 1 year ago • 1 comments

Self-service

  • [ ] I'd be willing to implement a fix

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": "[email protected]",
  "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 avatar Sep 09 '24 10:09 markandrus

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?

markandrus avatar Sep 11 '24 11:09 markandrus

I just ran into a similar (the same?) issue when trying to migrate away from fs-extra to using native node:fs methods.

-  fse.copySync(templateDir, newAppDir, { overwrite })
+  fs.cpSync(templateDir, newAppDir, { recursive: true, force: overwrite })

And here's the error message I'm getting

node:internal/fs/cp/cp-sync:56
  fsBinding.cpSyncCheckPaths(src, dest, opts.dereference, opts.recursive);
            ^

Error: ENOTDIR: not a directory, lstat '/home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/templates/ts'
    at cpSyncFn (node:internal/fs/cp/cp-sync:56:13)
    at Object.cpSync (node:fs:3147:3)
    at $ce (file:///home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/dist/create-cedar-app.js:583:816)
    at async rue (file:///home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/dist/create-cedar-app.js:598:857)
    at async file:///home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/dist/create-cedar-app.js:599:183
    at async file:///home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/dist/create-cedar-app.js:599:128 {
  errno: -20,
  code: 'ENOTDIR',
  syscall: 'lstat',
  path: '/home/runner/.yarn/berry/cache/create-cedar-app-file-313a48fa7e-10c0.zip/node_modules/create-cedar-app/templates/ts'
}

Sysinfo

  System:
    OS: macOS 15.2
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.12.0 - /private/var/folders/7j/9p56mwmj6jsfdr2h5_884j9w0000gn/T/xfs-6c7bc5a8/node
    Yarn: 4.12.0 - /private/var/folders/7j/9p56mwmj6jsfdr2h5_884j9w0000gn/T/xfs-6c7bc5a8/yarn

Using await fs.promises.cp() as a workaround worked for me as well

Tobbe avatar Dec 27 '25 07:12 Tobbe