Current Behavior
“Berry” is Yarn's name for Yarn 2 and later; this reproduction uses Yarn 4.15.0. When Yarn runs a workspace binary, it creates a temporary xfs-* directory containing wrappers for the selected node, yarn, node-gyp, and package binaries.
Yarn exposes that runtime directory and puts it first on PATH:
BERRY_BIN_FOLDER = /tmp/.../xfs-0a01a6bc
PATH = <BERRY_BIN_FOLDER><delimiter><existing toolchain PATH>
The first PATH entry is exactly the current BERRY_BIN_FOLDER value. The delimiter is : on macOS/Linux and ; on Windows; every remaining PATH entry is the pre-existing toolchain path.
The folder is deleted when the command exits. The next Yarn command receives a different random path even when the workspace, lockfile and available binaries are unchanged.
Two consecutive captures produced different folder names, but:
- the complete remaining
PATH was byte-for-byte identical;
- both folders contained the same 73 wrapper names; and
- every wrapper SHA-256 fingerprint matched.
The path string changed; the executable environment it represented did not.
The Nx client sends its runtime environment to the persistent daemon. The daemon compares the raw values and calls invalidateGraphCache() whenever a non-excluded value differs. Every yarn nx invocation therefore changes both BERRY_BIN_FOLDER and the first PATH segment, causing an unchanged graph to be rebuilt.
Observed daemon log on all three requests:
Graph recompute necessary due to env variable refresh.
Changed keys: PATH, BERRY_BIN_FOLDER
The public workflow reproduces this under stock Nx 23.1.1 on Windows, macOS and Ubuntu. In the large workspace that exposed the cost, six unchanged requests took 10.030-16.543 seconds. When the same graph was actually reused, requests completed in 266-270ms.
Expected Behavior
Nx needs two environment views:
| View |
Required behavior |
| Runtime environment |
Forward the latest full environment, including the current real Berry folder, so plugin workers can execute Yarn wrappers |
| Graph identity |
Compare stable inputs that can change projects, targets, dependencies, SDK selection or compiler behavior |
For graph comparison only, Nx should replace the random Berry value with a stable Yarn marker and remove only the matching temporary PATH segment. Every other PATH segment and SDK/compiler variable must remain significant.
Yarn and direct invocation must also remain distinct identities. Normalization must not collapse them together.
GitHub Repo
https://github.com/sdjayna/nx-daemon-reproductions
Successful cross-platform evidence run:
https://github.com/sdjayna/nx-daemon-reproductions/actions/runs/30946807413
Steps to Reproduce
- Install the reproduction with Yarn 4.15.0.
- Run
corepack yarn repro:berry.
- The script resets Nx and makes three unchanged
nx show projects requests.
- Inspect the emitted
invalidations array.
- Observe Berry/
PATH invalidation before every unchanged request.
Nx Report
Node : 22.22.2
OS : darwin-arm64
Native Target : aarch64-macos
yarn : 4.15.0
daemon : Available
nx : 23.1.1
The public workflow additionally reproduces the same invalidation on Node 24.18.0 Windows, macOS and Ubuntu runners.
Failure Logs
Graph recompute necessary due to env variable refresh.
Changed keys: PATH, BERRY_BIN_FOLDER
Windows reports the same two keys in the reverse iteration order: BERRY_BIN_FOLDER, PATH.
Package Manager Version
Yarn 4.15.0
Operating System
Additional Information
Draft PR #36565 implements runtime-versus-graph-identity separation:
#36565
There is no public Nx daemon environment-ignore configuration and no Yarn setting for a stable script bin directory. yarnpkg/berry#6130 documents the same temporary Node/PATH behavior in another persistent-tool integration.
Current Behavior
“Berry” is Yarn's name for Yarn 2 and later; this reproduction uses Yarn 4.15.0. When Yarn runs a workspace binary, it creates a temporary
xfs-*directory containing wrappers for the selectednode,yarn,node-gyp, and package binaries.Yarn exposes that runtime directory and puts it first on
PATH:The first
PATHentry is exactly the currentBERRY_BIN_FOLDERvalue. The delimiter is:on macOS/Linux and;on Windows; every remainingPATHentry is the pre-existing toolchain path.The folder is deleted when the command exits. The next Yarn command receives a different random path even when the workspace, lockfile and available binaries are unchanged.
Two consecutive captures produced different folder names, but:
PATHwas byte-for-byte identical;The path string changed; the executable environment it represented did not.
The Nx client sends its runtime environment to the persistent daemon. The daemon compares the raw values and calls
invalidateGraphCache()whenever a non-excluded value differs. Everyyarn nxinvocation therefore changes bothBERRY_BIN_FOLDERand the firstPATHsegment, causing an unchanged graph to be rebuilt.Observed daemon log on all three requests:
The public workflow reproduces this under stock Nx 23.1.1 on Windows, macOS and Ubuntu. In the large workspace that exposed the cost, six unchanged requests took 10.030-16.543 seconds. When the same graph was actually reused, requests completed in 266-270ms.
Expected Behavior
Nx needs two environment views:
For graph comparison only, Nx should replace the random Berry value with a stable Yarn marker and remove only the matching temporary
PATHsegment. Every otherPATHsegment and SDK/compiler variable must remain significant.Yarn and direct invocation must also remain distinct identities. Normalization must not collapse them together.
GitHub Repo
https://github.com/sdjayna/nx-daemon-reproductions
Successful cross-platform evidence run:
https://github.com/sdjayna/nx-daemon-reproductions/actions/runs/30946807413
Steps to Reproduce
corepack yarn repro:berry.nx show projectsrequests.invalidationsarray.PATHinvalidation before every unchanged request.Nx Report
The public workflow additionally reproduces the same invalidation on Node 24.18.0 Windows, macOS and Ubuntu runners.
Failure Logs
Windows reports the same two keys in the reverse iteration order:
BERRY_BIN_FOLDER, PATH.Package Manager Version
Yarn 4.15.0
Operating System
Additional Information
Draft PR #36565 implements runtime-versus-graph-identity separation:
#36565
There is no public Nx daemon environment-ignore configuration and no Yarn setting for a stable script bin directory. yarnpkg/berry#6130 documents the same temporary Node/
PATHbehavior in another persistent-tool integration.