Skip to content

pnpm silently relocates the store when the workspace is on another mount, ignoring a pre-populated one #14505

Description

@zkochan

Reproduction steps

  1. Build a container image that pre-populates the store at its default home location (/home/<user>/.local/share/pnpm/store), so a later install has nothing to download.
  2. Run a container from that image with the workspace bind-mounted, so the workspace is its own mount rather than a directory under $HOME.
  3. Install with a complete lockfile and watch the progress line:
Progress: resolved 2074, reused 0, downloaded 2074, added 2074, done

The pre-populated store is not used, and pnpm says nothing about why. reused 0 is the only hint, and it reads like a store that failed to populate rather than a store that was never consulted.

Describe the Bug

The relocation itself is deliberate and documented: resolve_store_dir probes whether the project can be hardlinked from the pnpm home directory, and when it cannot, re-resolves the store against the project's own volume:

if Sys::can_link_between_dirs(&pkg_root, pnpm_home_dir) {
    return home_default;
}
…
if mountpoint == pkg_root {
    return pkg_root.join("node_modules").join(".pnpm-store");
}
mountpoint.join(".pnpm-store")

A bind-mounted workspace is its own mount point, so mountpoint == pkg_root and the store becomes <workspace>/node_modules/.pnpm-store — empty, on every fresh container. The image's store is still sitting there, fully populated, and is never read.

The behaviour is right; the silence is the bug. Nothing is logged when the store moves away from the configured or default location, so the symptom a user sees is "my pre-populated image does nothing" with no thread to pull. It cost an afternoon to find here, and the same shape hits any CI that bakes a warm store into an image and mounts the workspace from elsewhere.

The TypeScript CLI has the same relocation in storePathRelativeToHome (pnpm11/store/path/src/index.ts) and is equally quiet about it.

Expected Behavior

When the store is resolved to somewhere other than the configured or default location, pnpm says so once, at debug level or above:

The store was moved to <workspace>/node_modules/.pnpm-store because <workspace> cannot be hardlinked from /home/user/.local/share/pnpm.
Set storeDir to keep it elsewhere.

pnpm doctor reporting the effective store path alongside the reason would cover the same ground for someone already suspicious.

Neither changes what an install does — the relocation stays, and a user who wants the home store can pin storeDir explicitly, which already skips this path entirely.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions