Skip to content

uninstall: make resilient to individual failures#21617

Merged
MikeMcQuaid merged 2 commits intoHomebrew:mainfrom
koddsson:uninstall-resilient-to-individual-failures
Feb 24, 2026
Merged

uninstall: make resilient to individual failures#21617
MikeMcQuaid merged 2 commits intoHomebrew:mainfrom
koddsson:uninstall-resilient-to-individual-failures

Conversation

@koddsson
Copy link
Contributor

Summary

Follow-up to #21615 which made cask error handling more resilient across commands. This PR extends that work specifically for brew uninstall to handle the case where one or more named arguments are unavailable:

  • When running brew uninstall A B C where one item (e.g. B) doesn't exist, the command previously halted before uninstalling anything. Now valid items are still uninstalled and errors are reported at the end.
  • Use to_formulae_and_casks_and_unavailable for name resolution so unavailable items are captured as values instead of raising
  • Add NoSuchKegError to the rescue clause in to_formulae_and_casks_and_unavailable
  • Collect per-cask exceptions in Cask::Uninstall.uninstall_casks following the pattern from Cask::Upgrade.upgrade_casks! so one failing cask doesn't prevent uninstalling the rest
  • Apply same per-cask error collection to the --zap loop
  • --force continues to silently ignore unavailable items (existing behavior)

Test plan

  • Updated existing unit test for cask uninstall error handling
  • Added integration test: uninstall testball alongside nonexistent name; verifies testball is uninstalled and exit code is non-zero
  • Added cask uninstall resilience test: when one cask fails, remaining casks are still uninstalled
  • brew typecheck passes
  • brew style --fix --changed passes
  • brew tests --only=cmd/uninstall passes
  • brew tests --only=cask/uninstall passes

🤖 Generated with Claude Code

When running `brew uninstall A B C` where one item is unavailable,
the entire command halted before uninstalling anything. Now errors
for unavailable items are collected and reported at the end while
valid items are still uninstalled.

- Use `to_formulae_and_casks_and_unavailable` for name resolution so
  unavailable items are captured as values instead of raising
- Add `NoSuchKegError` to the rescue clause in
  `to_formulae_and_casks_and_unavailable`
- Collect per-cask exceptions in `Cask::Uninstall.uninstall_casks`
  following the pattern from `Cask::Upgrade.upgrade_casks!`
- Apply same per-cask error collection to the zap loop
- Report unavailable errors via `ofail` after all uninstall work
  completes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@koddsson
Copy link
Contributor Author

I have similar changes to reinstall and upgrade, I can push them to this PR or make either one or two other PRs for those.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks again @koddsson!

@MikeMcQuaid
Copy link
Member

I have similar changes to reinstall and upgrade, I can push them to this PR or make either one or two other PRs for those.

One more combined PR sounds good!

@MikeMcQuaid MikeMcQuaid added this pull request to the merge queue Feb 24, 2026
Merged via the queue into Homebrew:main with commit a43dea8 Feb 24, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants