Resolve pi extension paths without hardcoding one specifier - #395
Merged
dannon merged 1 commit intoAug 3, 2026
Merged
Conversation
pi-mcp-adapter 2.12.0 added an "exports" map on Jul 24, and since exports are a closed list, that turned the deep "pi-mcp-adapter/index.ts" subpath we resolve into an error instead of a path. We depend on ^2.4.0, so every fresh install since then resolves to 2.12+ and dies on startup with an ERR_PACKAGE_PATH_NOT_EXPORTED stack before printing a single line -- meaning `npm install -g @galaxyproject/loom` is broken on npm right now. Our lockfile pins 2.9.0, which is exactly why nothing local caught it; smoke:pack, which installs without the lockfile, is the one check that did. There's no single specifier that covers both shapes. A package with an exports map only answers the bare name, and a package without one (pi-mcp-adapter <=2.11.0, and pi-web-access today) declares no "main", so only the subpath resolves. So try bare first and fall back to the subpath. That also covers pi-web-access, which is the same pattern one line down and would break the same way the day it grows an exports map. Verified both directions: against the pinned 2.9.0 the fallback path works, and smoke:pack -- which installs fresh and lands on 2.15.0 -- goes from failing on main to green.
dannon
marked this pull request as ready for review
August 3, 2026 02:33
This was referenced Aug 3, 2026
Merged
dannon
added a commit
that referenced
this pull request
Aug 10, 2026
Every check in the build job runs against the pinned tree, which is exactly the tree no user has. #395 is what that costs: pi-mcp-adapter published an exports map, our lockfile stayed on the version before it, and typecheck, tests, and packaging all stayed green while `npm i -g @galaxyproject/loom` died on the first line of startup. smoke:pack is the one check that installs without the lockfile, and it caught that -- it just wasn't wired up to run anywhere. Note this step is deliberately not hermetic. It hits the network and can go red because a dependency published something broken rather than because the PR did. That's the job: a failure here means someone installing right now would hit the same thing.
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.
npm install -g @galaxyproject/loomis broken on npm right now, and has been since Jul 24. A fresh install dies on startup before printing anything:pi-mcp-adapter 2.12.0 (published 2026-07-24) added an
exportsmap. Exports are a closed list, so the deeppi-mcp-adapter/index.tssubpath we resolve stopped being a path and started being an error. We depend on^2.4.0, so every fresh install since then resolves to 2.12+ and hits it. I confirmed against the actual published 0.5.1 tarball, not just locally.Our lockfile pins 2.9.0, which is precisely why nothing caught this in dev --
npm ci, tests, typecheck and packaging all use the pinned version and stay happy.smoke:packis the only check that installs without the lockfile, and it's been failing on main for this. It was doing its job; we just don't run it in CI.The fix
There's no single specifier that works for both package shapes:
pkg/index.tspkgmainmainA package with an exports map only answers the bare name; a package without one declares no
main, so only the subpath resolves. SoresolvePiExtensionDirtries bare first and falls back to the subpath, and if both fail it throws something actionable naming both attempts instead of a bare Node stack.This covers
pi-web-accesstoo -- same pattern on the next line, no exports map yet, and it would break identically the day it grows one.Verification
Both directions, since the whole bug was that only one half was ever exercised:
node bin/loom.js --helpexits 0npm run smoke:pack, which installs fresh and lands on 2.15.0 (bare path): fails on main, green hereWorth a follow-up, not in here
Dev runs 2.9.0 while every real user gets 2.15.0. That gap is what let this ship, and it'll let the next one ship too. Bumping the lockfile would close it but can surface genuine behavior changes in the adapter, so it deserves its own PR rather than riding along with a startup fix.
smoke:packalso isn't in.github/workflows/build.yml-- if it were, this would have been caught on the first PR after Jul 24.