You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[SEVERE] upgrade --self --dry-run performs a real @latest install and can downgrade previews #2295
Squad 2.0.0-preview.1 ignores --dry-run when it is combined with squad upgrade --self. The command proceeds into a real global install of @bradygaster/squad-cli@latest. On the tested preview installation, latest resolved to 1.0.0, so a successful run would both mutate the machine during a dry run and downgrade the preview CLI. Only an unrelated EPERM prevented the mutation.
The default self-upgrade target also ignores the installed channel. A preview/insider install should stay on that channel unless the user explicitly requests another one, and --insider should be honored.
Environment
Squad CLI 2.0.0-preview.1, installed from the exact published release tarball
The command exited non-zero only because the global installation could not be unlinked. Had the install succeeded, the preview CLI would have been replaced by 1.0.0.
Expected
--dry-run must make upgrade --self side-effect-free.
The output should describe the package/version/channel that would be installed.
A preview/insider installation should default to its installed channel rather than latest.
--insider must select the insider/preview channel consistently for self-upgrade.
Impact / Severity
SEVERE. This violates the dry-run safety contract and can silently downgrade or replace a global CLI installation. The observed machine was protected only by an unrelated filesystem error.
Proposed fix
Check dryRun before any package-manager spawn in the self-upgrade path.
Resolve the installed package version/channel and preserve preview/insider by default.
Make --insider override channel resolution explicitly.
Add injectable-spawn tests for npm/pnpm/yarn proving all --self --dry-run combinations execute zero mutations and print the resolved target.
Adding the backend-migration variant of this dry-run defect for stable 1.1.0, pinned to release commit c24da2aad2ab7576f6b68dec2bc50b2fe2dc7a8a:
squad upgrade --state-backend orphan --dry-run
This does not require --self. In the released upgrade dispatcher, dryRun is passed to runUpgrade(), which previews and returns. The dispatcher then calls migrateStateBackend(dest, upgradeStateBackend) unconditionally.
The migration function has no dry-run option. It can create the state branch, import decisions/histories, remove their working-tree copies, rewrite configuration, install hooks, and update .gitignore, despite the command's preview-only promise.
I checked #2303: its dispatcher change explicitly skips backend migration and hook installation during a dry run, so that merged fix covers this variant too. I am adding the stable-version evidence here rather than opening a duplicate or claiming a regression in the fix. Since 1.1.0 is still listed as the latest stable release, please include this behavior in stable release notes and identify the first stable version with the fix.
There is no fixed stable release to point to yet. I checked the release tags and package dist-tags: v1.1.0 is still latest and predates #2303. The fix is included in v2.0.0-preview.2 and v2.0.0-preview.3, both prereleases. It covers the backend-migration dry-run variant described here as well as --self. I have prepared local release-note wording for both variants to carry into the next stable release; those notes are not published, and no stable version or publication date is assigned.
Activity
fix(cli): 2.0.0-preview.2 upgrade/health fixes from dogfooding
fix(cli): 2.0.0-preview.2 upgrade/health fixes from dogfooding (#2303)
dat-intellis commentedon Nov 8, 2026
Adding the backend-migration variant of this dry-run defect for stable 1.1.0, pinned to release commit
c24da2aad2ab7576f6b68dec2bc50b2fe2dc7a8a:This does not require
--self. In the released upgrade dispatcher,dryRunis passed torunUpgrade(), which previews and returns. The dispatcher then callsmigrateStateBackend(dest, upgradeStateBackend)unconditionally.The migration function has no dry-run option. It can create the state branch, import decisions/histories, remove their working-tree copies, rewrite configuration, install hooks, and update
.gitignore, despite the command's preview-only promise.I checked #2303: its dispatcher change explicitly skips backend migration and hook installation during a dry run, so that merged fix covers this variant too. I am adding the stable-version evidence here rather than opening a duplicate or claiming a regression in the fix. Since 1.1.0 is still listed as the latest stable release, please include this behavior in stable release notes and identify the first stable version with the fix.
tamirdresher commentedon Nov 9, 2026
There is no fixed stable release to point to yet. I checked the release tags and package dist-tags: v1.1.0 is still latest and predates #2303. The fix is included in v2.0.0-preview.2 and v2.0.0-preview.3, both prereleases. It covers the backend-migration dry-run variant described here as well as --self. I have prepared local release-note wording for both variants to carry into the next stable release; those notes are not published, and no stable version or publication date is assigned.