Self-service
Describe the bug
Scenario
Two parallel jobs are running.
Job 1 - Creates temporary files that are deleted after the process ends
Job 2 - Runs yarn pack or calls genPackList from @yarnpkg/plugin-pack
Explanation
genPackList calls walk - a function that traverses the folder structure to determine which files are part of the pack. In this process, walk calls cwdFs.lstatPromise(here) to determine wether the path belongs to a directory or a normal file. If its a directory, it calls cwdFs.readdirPromise(here) to get a list of all paths, which are added to the DFS traversal stack; each discovered path goes through the same process.
The race condition manifests within a traversal loop, after readdir. In the scenario where Job 1 created a file, in a directory being processed by the walk function, the file will be added to the DFS traversal stack. However, by the time that this path is popped, before lstat is called, it may have already been deleted by Job 1
Result
This produces a failure with the following error
> yarn pack
...
Error: ENOENT: no such file or directory, lstat '$PATH_TO_TEMPORARY_FILE'] {
errno: -2,
code: 'ENOENT',
syscall: 'lstat',
path: '$PATH_TO_TEMPORARY_FILE'
}
To reproduce
- Create a workspace
- Create a script that adds files -- wait 1 second -- then deletes the file
- Create another script that calls the script on step 2, as well as
yarn pack, executing them in parallel
- Call the script created in step 3
The results may be mixed and may require tweaking the 1 second variable. When reproduced correctly, you should see the lstat error mentioned above.
Environment
System:
OS: macOS 26.4.1
CPU: (12) arm64 Apple M3 Pro
Binaries:
Node: 22.20.0 - /Users/georgetaveras/.asdf/installs/nodejs/22.20.0/bin/node
Yarn: 4.11.0 - /opt/homebrew/bin/yarn
npm: 10.9.3 - /Users/georgetaveras/.asdf/plugins/nodejs/shims/npm
Additional context
Proposal
Catch errors from lstat, ignore if the file no longer exists.
Self-service
Describe the bug
Scenario
Two parallel jobs are running.
Job 1 - Creates temporary files that are deleted after the process ends
Job 2 - Runs
yarn packor callsgenPackListfrom@yarnpkg/plugin-packExplanation
genPackListcallswalk- a function that traverses the folder structure to determine which files are part of the pack. In this process,walkcallscwdFs.lstatPromise(here) to determine wether the path belongs to a directory or a normal file. If its a directory, it callscwdFs.readdirPromise(here) to get a list of all paths, which are added to the DFS traversal stack; each discovered path goes through the same process.The race condition manifests within a traversal loop, after
readdir. In the scenario where Job 1 created a file, in a directory being processed by thewalkfunction, the file will be added to the DFS traversal stack. However, by the time that this path is popped, beforelstatis called, it may have already been deleted by Job 1Result
This produces a failure with the following error
To reproduce
yarn pack, executing them in parallelThe results may be mixed and may require tweaking the 1 second variable. When reproduced correctly, you should see the
lstaterror mentioned above.Environment
System: OS: macOS 26.4.1 CPU: (12) arm64 Apple M3 Pro Binaries: Node: 22.20.0 - /Users/georgetaveras/.asdf/installs/nodejs/22.20.0/bin/node Yarn: 4.11.0 - /opt/homebrew/bin/yarn npm: 10.9.3 - /Users/georgetaveras/.asdf/plugins/nodejs/shims/npmAdditional context
Proposal
Catch errors from
lstat, ignore if the file no longer exists.