Summary
When an extension is already installed, running:
gh extension install OWNER/REPO --pin <tag> --force
appears to route through upgrade logic and installs latest, instead of honoring the pinned tag.
Environment
- OS: Linux
- gh version: 2.89.0 (2026-03-26)
- Example extension: github/gh-aw
Reproduction
- Install an older version:
gh extension install github/gh-aw --pin v0.74.8
- Verify:
gh extension list
- Attempt forced pinned install:
gh extension install github/gh-aw --pin v0.75.0 --force
- Verify:
gh extension list
Actual Behavior
The command upgrades to latest (for example v0.76.1) and prints upgrade-style output such as:
[aw]: upgraded from v0.74.8 to v0.76.1
✓ Successfully checked extension upgrades
Result: installed version is latest, not the pinned version.
Expected Behavior
When --pin is provided, it should be honored even if --force is also set and the extension is already installed.
Workaround
Removing first, then installing pinned works:
gh extension remove gh-aw
gh extension install github/gh-aw --pin v0.75.0
This correctly installs the pinned version.
Additional Context
This seems to happen because install with --force on an already-installed extension takes the upgrade path, and that path ignores pin for binary extensions (uses latest).
Summary
When an extension is already installed, running:
gh extension install OWNER/REPO --pin <tag> --forceappears to route through upgrade logic and installs latest, instead of honoring the pinned tag.
Environment
Reproduction
gh extension install github/gh-aw --pin v0.74.8gh extension listgh extension install github/gh-aw --pin v0.75.0 --forcegh extension listActual Behavior
The command upgrades to latest (for example
v0.76.1) and prints upgrade-style output such as:Result: installed version is latest, not the pinned version.
Expected Behavior
When
--pinis provided, it should be honored even if--forceis also set and the extension is already installed.Workaround
Removing first, then installing pinned works:
This correctly installs the pinned version.
Additional Context
This seems to happen because install with
--forceon an already-installed extension takes the upgrade path, and that path ignores pin for binary extensions (uses latest).