Visitar URL original
Global virtual store: a git-hosted dependency is not built in a new slot (stale "\tbuilt" store index row) · Issue #17224 · pnpm/pnpm · GitHub
Skip to content

Global virtual store: a git-hosted dependency is not built in a new slot (stale "\tbuilt" store index row) #17224

Closed

Description

@rubnogueira

Verify latest release

  • I verified that the issue exists in the latest pnpm release (12.15.0)

pnpm version

12.15.0

Which area(s) of pnpm are affected?

Store

Link to the code that reproduces this issue

https://github.com/rubnogueira/pnpm-gvs-built-row

Reproduction steps

  1. Clone https://github.com/rubnogueira/pnpm-gvs-built-row.
  2. Run bash repro.sh. It needs network access to GitHub and the npm registry, and a C++ toolchain for node-gyp.

The repo has two projects that share one store (storeDir: ../store) with enableGlobalVirtualStore: true. Both depend on the same commit of a native addon from GitHub, and both allow its build:

# project-a/pnpm-workspace.yaml (project-b is the same, but nan: 2.26.2)
storeDir: ../store
cacheDir: ../cache
enableGlobalVirtualStore: true
overrides:
  nan: 2.27.0
allowBuilds:
  node-expat@https://codeload.github.com/xmppo/node-expat/tar.gz/78e559baa908942097330f7967dfbf623ebc2529: true
{ "dependencies": { "node-expat": "github:xmppo/node-expat#78e559baa908942097330f7967dfbf623ebc2529" } }

The only difference is the nan override. It gives node-expat a different dependency, so project-b needs a new slot for the same node-expat commit. repro.sh clears the store, installs project-a, then project-b, and checks for node_modules/node-expat/build/Release/*.node:

project-a: built
project-b: NOT BUILT

Describe the Bug

pnpm builds a git-hosted dependency only in the first global virtual store slot it creates for that dependency. A later slot for the same commit is linked without running the build. pnpm exits 0 and prints no warning; the app fails at runtime when it loads the addon.

What we found:

  • The two slots are store/v11/links/@/node-expat/2.4.1/<hash-a> and …/<hash-b>.
  • The store index (store/v11/index.db, table package_index) has one row per git-hosted package, not one per slot: https://codeload.github.com/xmppo/node-expat/tar.gz/78e559b…\tbuilt. pnpm seems to read this row as "already built" and skips the build for every later slot.
  • These do not build the new slot: pnpm rebuild, pnpm install --force, sideEffectsCache: false, and deleting only the slot folder before an install.
  • Deleting the slot folder and the \tbuilt row makes the next install build the slot. pnpm then writes the row again, so the next new slot has the same problem.
  • A git+file:// dependency fails the same way (row key git+file://…#<commit>\tbuilt). A file: tarball with an install script is built in both slots, so the problem is specific to git-hosted dependencies.

We hit this in a monorepo whose Docker dev container keeps the store in a volume. A dependency change gave a GitHub-hosted native addon a new slot, and the service crashed at startup. Our workaround runs after each install: it finds slots without the build output, deletes them and the \tbuilt row, and installs again.

Possibly related: #16642 (a later install trusts a broken slot).

Expected Behavior

pnpm runs the build of an allowed git-hosted dependency in every new slot, as it does for the first one:

project-a: built
project-b: built

Which Node.js version are you using?

24.22.0 (also seen with 24.22.1)

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is?

Debian 13 (x86_64); also seen in a Docker container

Activity

  1. github-actions commented on Oct 22, 2026

    @github-actions
    Contributor

    @rubnogueira, are you planning to open a pull request for this? If so, reply here and a maintainer will assign the issue to you, so nobody else starts on the same fix.

  2. rubnogueira commented on Oct 22, 2026

    @rubnogueira
    ContributorAuthor

    Yes

  3. rubnogueira commented on Oct 22, 2026

    @rubnogueira
    ContributorAuthor

    #17231 fixes this. It covers the whole issue.

    The cause is the store-index row the git fetcher writes. Its requiresBuild recorded whether the package needed prepare, not whether it has install scripts. node-expat has an install script and no prepare, so the row said "no build". Later installs trusted the row and skipped the build in every new slot. The same happened when reinstalling into a fresh node_modules from a warm store.

    The PR stores requiresBuild from the package's files, as for any other package. It also re-derives the value for rows already in a store, so existing stores, such as one kept in a Docker volume, are fixed without clearing the store or deleting the \tbuilt row. pnpm 11 computes this correctly and is not affected.


    Written by an agent (Claude Code, claude-opus-5-5).

  4. added a commit that references this issue on Oct 22, 2026
    b0bff65
  5. added a commit that references this issue on Oct 22, 2026
    be4d6f5
  6. added a commit that references this issue on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions