Fix Windows update and reset recovery reporting - #280
Merged
Salil Das (sadlilas) merged 2 commits intoAug 27, 2026
Merged
Conversation
Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
On POSIX, when uninstall succeeds but reinstall fails, reset() was returning successfully (exit 0) even though the user was left with no Amplifier installed. Changed to raise ClickException to report the failure correctly. Also enhanced the uv_utils comment to document both reasons the batch script fully-qualifies Windows utilities: (a) Git for Windows shadowing GNU find on PATH, and (b) cmd.exe resolution order checking the current directory before PATH. Extended test coverage for Windows batching and added explicit test for POSIX reset failure on reinstall error.
Salil Das (sadlilas)
marked this pull request as ready for review
August 27, 2026 02:38
Salil Das (sadlilas)
deleted the
fix/windows-update-reset-cache-recovery
branch
August 27, 2026 02:39
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.
Summary
Hit on a real native-Windows machine while running
amplifier update. Fixing thereporting there led to the same class of bug in
reset, which shares the deferredtool-swap machinery.
Amplifier installed
System32Root cause
Windows self-update reported the wrong outcome. On Windows,
execute_self_updatehands the install to a deferred
.cmdand returns immediately. It returnedupdated=["amplifier"], so the CLI printed✓ Update complete— for an install thathad not started yet. A
messagesline did say the update would finish in the newwindow, so the information was present, but the headline contradicted it.
Reset reported success after a partial cleanup. A locked file makes
shutil.rmtreefail partway.rmtree_robustre-raises,clear_download_cachecatches
OSErrorand returns(0, False)— and_remove_amplifier_dirhad noelsebranch on that result, so it counted nothing and still returned
True.reset()discarded the return value entirely and printed
Reset complete!with exit 0, thenstaged the reinstall.
To be precise about the blast radius: the half-deleted cache directory is not
left permanently broken.
amplifier-foundationvalidates a cached clone before usingit (
sources/git.py_verify_clone_integrity) and has no incremental-update path —it deletes and re-clones on any integrity failure. So a cache directory that lost its
.gitself-heals on the next load. The defect being fixed here is that reset liesabout having succeeded, which is invisible to the user and undetectable by any
script or CI step driving it — not that it corrupts state permanently.
Reset also exited 0 when the reinstall failed. On the POSIX path
_uninstall_amplifierruns first, so a failed_install_amplifierleaves the userwith no Amplifier at all — and the command returned normally, reporting that as
success. This is the same honest-exit-code defect as above, with a worse outcome.
The deferred script relied on PATH for its utilities. Two independent problems.
Git for Windows ships a GNU
find.exeinusr\bin, which its installer will place onPATH; GNU
findreads"<pid>"as a path rather than a pattern and exits 1, soif not errorlevel 1goes false and the PID wait loop is skipped. Separately,cmd.exeresolves a bare command name from the current directory beforeconsulting PATH, and the finisher inherits Amplifier's cwd — typically a user's
project directory — so a stray
ping.exeortasklist.exethere would be executed.Both are closed by spelling out
%SystemRoot%\System32\...; the second reason is whypingandtasklistare qualified and not justfind.Skipping the wait loop is partly masked today by the script's own retry-with-backoff
(the required step retries 10 times at ~3s), so this is a correctness fix rather than
a hard failure in the common case.
Verification
uv run pytest -q— 1449 passed, 13 deselected, 1 xfaileduv run pytest -q tests/test_windows_update_reset.py— 15 passedundeletable directory, not a mocked failure): before,
amplifier reset -ydeleted.git/configand.git/objects/pack/*, left the locked file, printedReset complete!and exited 0; after, it exits 1 and names the failurereinstall fails — exit code goes 0 → 1
finisher
usr/binfirst on PATHUpdate staged, and alock-release reset retry completed successfully
Breaking changes
amplifier resetnow exits nonzero when cleanup or reinstall fails, where itpreviously always exited 0. Anything scripting
resetthat assumed a 0 exit will nowcorrectly see the failure.