fix: resolve @bitgo/* siblings into npm-shrinkwrap.json - #9404
Open
lokesh-bitgo wants to merge 1 commit into
Open
fix: resolve @bitgo/* siblings into npm-shrinkwrap.json#9404lokesh-bitgo wants to merge 1 commit into
lokesh-bitgo wants to merge 1 commit into
Conversation
Contributor
zahin-mohammad
approved these changes
Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket: WCI-1200
Issue
Reported : running
npm install bitgo(the bundled all-coins SDKinstall, not modular) reports a successful install, but none of the
@bitgo/*sibling packages (
@bitgo/sdk-api,@bitgo/sdk-core, all@bitgo/sdk-coin-*,etc. — 89 packages total) land in
node_modules.require('bitgo')then failsimmediately with:
Modular install (
@bitgo/sdk-api+@bitgo/sdk-coin-{name}+register())is unaffected — this only breaks the bundled
bitgopackage install path.Confirmed reproduction
Installed the real, published
bitgo@52.4.1from the real npm registry in anempty directory:
node_modules/@bitgo/does not existrequire('bitgo')throwsMODULE_NOT_FOUND: Cannot find module '@bitgo/sdk-core'Root cause
scripts/generate-bitgo-shrinkwrap.tsruns at pack time (prepackfor thebitgomodule, gated byBITGO_GENERATE_SHRINKWRAP=truein the releaseworkflow) and generates the
npm-shrinkwrap.jsonshipped inside the publishedbitgotarball. The previous implementation:Built an isolated temp
package.jsonwith all@bitgo/*siblingdependencies filtered out, to avoid requiring sibling versions that
might not yet be published to the registry at release time.
Ran
npm install --package-lock-only+npm shrinkwrapagainst thatstripped manifest. Since siblings were never in the manifest, npm never
resolved them — no
packages["node_modules/@bitgo/<name>"]entries weregenerated for them.
"Restored" the siblings afterward, but only into:
shrinkwrap.dependencies, andshrinkwrap.packages[''].dependenciesBoth of these are just metadata ("the root package declares a
dependency on X") — not install instructions. The actual install plan npm
uses to populate
node_modulesin an npm v7+ lockfile lives in thepackagesmap keyed bynode_modules/<name>paths, and no such entrieswere ever created for the 89 siblings.
On the real npmjs.com registry, published versions carry
_hasShrinkwrap: truein their packument metadata. When that flag is set, npm treats the bundled
npm-shrinkwrap.jsonas strictly authoritative for that subtree — anydependency listed only in
packages[''].dependencieswithout a matchingresolved
packages[...]entry is silently dropped from the install ratherthan falling back to normal resolution. That's the exact mechanism causing the
reported
MODULE_NOT_FOUND.(Confirmed locally: local tarball installs and a local Verdaccio registry do
not reproduce this, because neither sets
_hasShrinkwrap: true— only thereal npmjs.com registry does. This matches an explicitly unresolved
open question already flagged in the original ticket, WCN-604, when the
shrinkwrap generation was first introduced.)
Origin
Introduced in commit
8885c03a87"fix(bitgo): generate npm-shrinkwrap.json atpack time" (WCN-604 — "Ship npm-shrinkwrap.json + overrides to fix npm audit
gap for consumers"). That ticket's goal was legitimate and security-driven:
yarn
resolutionspin safe transitive dependency versions internally, but npmconsumers never got those pins, so
npm auditon the publishedbitgopackage showed 51 vulnerabilities (3 critical, 13 high) that internal
yarn-based CI didn't catch. This fix is a side effect of the workaround chosen
for "siblings aren't published yet at pack time" — it never accounted for
npm's lockfile requiring full
packagesentries for every listed dependency.Fix
Minimal, targeted change to
generate-bitgo-shrinkwrap.ts:@bitgo/*siblings from the temp package.json beforeresolution. They now resolve as part of the same
npm install --package-lock-only+npm shrinkwraprun as every other dependency,against the real registry.
lerna publishpublishes packages independency-topological order, so by the time
bitgo(which depends onevery sibling) is packed, the sibling versions it references are already
live on the registry.
dependencies/packages[''].dependenciesmetadata — no longer neededsince nothing is stripped anymore.
@bitgo/*sibling has a realpackages["node_modules/@bitgo/<name>"]entry in the resulting shrinkwrap. If any are missing, the script throws
and the release fails — correct behavior, since a failed release beats a
silently broken shrinkwrap shipped to every consumer.
Validation performed
npm-shrinkwrap.jsongenerated successfully, all 89@bitgo/*siblingsreceived full
version/resolved/integrity/dependenciesentries,and the new safety check passed with zero unresolved siblings.
version (
999.999.999) and reran — script failed with exit code1instead of silently producing a broken shrinkwrap.
newly-generated (fixed) shrinkwrap into a locally-unpacked copy of the real
published
bitgo@52.4.1tarball, rannpm install, and confirmed:@bitgo/*packages installed (up from 0 before the fix)require('@bitgo/sdk-core')andrequire('@bitgo/sdk-api')resolve andload successfully
MODULE_NOT_FOUND: Cannot find module '@bitgo/sdk-core'error is completely gone
no-console/no-syncstyle warnings remain, unchanged in kind and countfrom before this change).
Known unrelated issue found during testing
After this fix,
require('bitgo')against the real published tarballprogresses much further but then hits an unrelated, pre-existing error deep in
a transitive dependency:
This is a separate ESM/CJS packaging incompatibility in
rpc-websockets's owndependency on
uuid, unrelated to shrinkwrap generation. Worth a follow-upticket; out of scope for this PR.
References
audit gap for consumers
8885c03a87"fix(bitgo): generate npm-shrinkwrap.json atpack time"
cb0124ab34"fix(scripts): skip overrides that arealready direct bitgo deps"
scripts/generate-bitgo-shrinkwrap.ts