Skip to content

Yarn Berry temporary PATH invalidates an unchanged daemon graph #36564

Description

@sdjayna

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

  1. Install the reproduction with Yarn 4.15.0.
  2. Run corepack yarn repro:berry.
  3. The script resets Nx and makes three unchanged nx show projects requests.
  4. Inspect the emitted invalidations array.
  5. 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

  • macOS
  • Windows
  • Linux

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions