Skip to content

specrew update: Spec Kit CLI network failure fail-hards (exit 1) and masks a successful Specrew update #2886

@alonf

Description

@alonf

Summary

specrew update --all treats a Spec Kit CLI upgrade failure as fatal: it Write-Errors and exit 1s even when the Specrew portion of the update already completed successfully. A transient/network failure reaching PyPI (to upgrade specify-cli) therefore makes a fully-successful Specrew sync look like a total failure.

Reported by

A tester on Windows / PowerShell 7.6.x, installed Specrew 0.38.0 from PSGallery, in a corporate/Azure-hosted repo (C:\_WS_\Azure\Repos\...). The PyPI fetch was reset by the network (os error 10054).

Evidence (tester log, abridged)

The Specrew sync completed — the project synced 0.27.5 → 0.38.0 (all .specify/.claude/.cursor/.github/.agents/.squad assets, refocus-hooks for all 5 hosts, coordinator instructions, .specrew/config.yml):

Specrew  module-version-detected  0.27.5 -> 0.38.0
... (dozens of created/updated/preserved asset rows) ...
Specrew  updated   ...\.specrew\config.yml

Then it failed only on the Spec Kit CLI upgrade:

- specify-cli==0.9.0
  error: Failed to fetch: `https://pypi.org/simple/packaging/`
  Caused by: An existing connection was forcibly closed by the remote host. (os error 10054)
...
Spec Kit   failed   Failed to upgrade Spec Kit to 0.9.0.

Write-Error: ...\Specrew\0.38.0\scripts\specrew-update.ps1:1567
1567 |      Write-Error $installFailureMessage
     | Failed to upgrade Spec Kit to 0.9.0.

The root cause of the failure is environmental (PyPI unreachable — proxy/firewall/VPN/AV resetting the connection, or a PyPI transient), not a Specrew defect. The defect is that Specrew turns it into a hard, whole-command failure.

Root cause (code)

In scripts/specrew-update.ps1 (line numbers from the 0.33.0 tree; the 0.38.0 build hits the terminal Write-Error at :1567):

  • The Spec Kit upgrade throws on any failure: throw ("Failed to upgrade Spec Kit to {0}." -f $Version) (~line 612).
  • That is caught into $installFailureMessage (~line 1507).
  • At the end: if ($installFailureMessage) { Write-Error $installFailureMessage; exit 1 } (~lines 1558-1560).

So the network-dependent, separable Spec Kit CLI step is fatal to the whole command and masks the successful Specrew update.

Impact

  • Looks like a total failure when the project actually updated cleanly → confusing, especially on corporate networks/proxies/VPNs where PyPI is commonly blocked or reset.
  • exit 1 makes any wrapper/CI treat the run as failed even though Specrew assets are at 0.38.0.

Proposed fix

  • Fail-soft on the Spec Kit CLI upgrade: warn + record the step as failed / retry-later (the summary already prints a Spec Kit failed row — make that the only signal), and exit 0 for the completed Specrew portion (or a distinct non-fatal exit code so callers can tell "Specrew updated, Spec Kit pending").
  • Distinguish a network failure (retry later / configure proxy) from a real incompatibility in the message; consider a short retry/backoff on the uv fetch.
  • Document re-running just the Spec Kit step (specrew update --spec-kit) once the network allows, instead of redoing --all.

Environment

  • OS: Windows; PowerShell 7.6.x
  • Specrew: 0.38.0 (PSGallery)
  • Spec Kit target: specify-cli 0.9.0 (via uv)
  • Network: corporate/Azure; PyPI connection reset (os error 10054)

Minor follow-ups surfaced by the same run (could be split into separate issues)

  • extensions/specrew-speckit/hooks is an empty .gitkeep placeholder, yet the update prints a scary skipped-missing-source line. Tidy so it doesn't (the real hooks deploy via deploy-refocus-hooks.ps1, which ran fine for all 5 hosts).
  • specrew --version run outside a project prints Project baseline ... (not found) / Compatibility: UNKNOWN. Clearer to say "not inside a Specrew project."
  • template-baseline-unavailable: Could not locate module version 0.27.5 on a big version jump (old module not cached locally → template-diff degrades to managed-asset-only). Expected, but worth a clearer message that this is a degradation, not an error.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions