Conversation
installGeneration wrote a pnpm-workspace.yaml into the staging workspace only when build approvals existed to forward. Without one, pnpm resolved the workspace root by walking the ancestor chain — and when a directory above the staging tree is itself a pnpm workspace (a home folder used as one is the usual case), that workspace claimed the install together with ITS store. Its node_modules records the store of a different pnpm major than the bundled one, so pnpm exits with ERR_PNPM_UNEXPECTED_STORE in a few hundred milliseconds and the market reports the plugin as unbuildable. Reproduced on macOS with ~/pnpm-workspace.yaml + ~/node_modules linked to store v11 (packageManager pnpm@11): identical staging trees succeed in /tmp, fail under $HOME without a workspace file, and succeed with one. dshmarket classifies the failure and points the user at the PROFILE's node_modules, which never mismatched — the wrong advice for this variant. - stageBuildApprovals always writes the workspace file now; with no approvals it is a minimal manifest (packages: ['.']) that pins the workspace root to the staging tree itself. - storeMismatch() recognizes the failure by its code and extracts both stores; a mismatch that survives triggers exactly one retry in a fresh staging workspace (disposable by construction — a failed install discards it). - The terminal failure detail names both stores and the ancestor-workspace cause instead of a bare code line. Verified end to end with the app's bundled node+pnpm against the shipped registry flow: install without any ancestor workspace succeeds; a simulated first-attempt mismatch retries and succeeds (2 pnpm calls, traced); a persistent mismatch fails with the actionable detail; storeMismatch() returns undefined for unrelated failures.
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.
Problem
installGenerationwrites apnpm-workspace.yamlinto the staging workspace only when build approvals exist to forward. Without one, pnpm resolves the workspace root by walking the ancestor chain — and when a directory above the staging tree is itself a pnpm workspace (a home folder used as one is the usual case), that workspace claims the install together with its store. Itsnode_modules/.modules.yamlrecords the store of a different pnpm major than the bundled one, so pnpm exits withERR_PNPM_UNEXPECTED_STOREin a few hundred milliseconds and the market reports the plugin as unbuildable.Reproduction on macOS (
~/pnpm-workspace.yaml+~/node_moduleslinked to storev11,packageManager: pnpm@11, bundled pnpm10.34.5):/tmp, no workspace file$HOME, no workspace fileERR_PNPM_UNEXPECTED_STORE(v11 vs v10), exit 1 in ~234 ms$HOME, withpnpm-workspace.yamldshmarket classifies the failure and advises relinking the profile's
node_modules— which never mismatched, so the advice cannot fix it.Fix
stageBuildApprovalsalways writes the workspace file now. With no approvals it is a minimal manifest (packages: ['.']) that pins the workspace root to the staging tree itself.storeMismatch()recognizes the failure by its code and extracts both named stores; a mismatch that survives triggers exactly one retry in a fresh staging workspace (disposable by construction — a failed install already discards staging, so the retry cannot touch anything outside it).Testing
End to end with the app's bundled node+pnpm against the real registry flow (
installGenerationimported from the patched file):ok: trueok: falsewith the actionable detail naming both storesstoreMismatch()returnsundefinedfor unrelated failuresnode --checkclean; diff is confined topackages/dsh-desktop-market-installer/generations/installer.mjs