Windows native updater reports "Successfully updated" but never swaps the running binary — infinite no-op updates

Resolved 💬 2 comments Opened Jun 22, 2026 by Talnerith Closed Jun 26, 2026

Summary

On a Windows native install, claude update repeatedly prints Successfully updated from 2.1.183 to version 2.1.185 and writes "outcome":"success" to .last-update-result.json, but claude --version keeps reporting the old version forever. The new version is fully downloaded and staged, but the activation step (replacing ~/.local/bin/claude.exe) silently never happens.

Environment

  • Windows 11 Pro (26200)
  • Claude Code, native install (installMethod: native)
  • Stuck updating 2.1.183 → 2.1.185

Symptom

> claude --version
2.1.183 (Claude Code)
> claude update
Current version: 2.1.183
Checking for updates to latest version...
Updating to 2.1.185...
Successfully updated from 2.1.183 to version 2.1.185
> claude --version
2.1.183 (Claude Code)

Reproduces on a fresh reboot with no other Claude process running.

Root cause (diagnosed)

The Windows native layout stores full per-version binaries in ~/.local/share/claude/versions/<ver> and makes one active by copying it to ~/.local/bin/claude.exe (no symlink/launcher on Windows). Activation therefore must overwrite the exe that claude update is itself executing from. Windows won't overwrite a running .exe, so the copy can't proceed — but the updater swallows this and records success anyway.

Evidence:

  • versions\2.1.185 exists, is a genuine working 2.1.185 binary (distinct SHA-256; running it directly prints 2.1.185).
  • bin\claude.exe SHA-256 is byte-identical to versions\2.1.183.
  • During a "successful" update, a filesystem watch shows zero files created/modified — no temp copy, and crucially no claude.exe.old/.bak rename attempt in bin\. The updater never even attempts the rename-then-replace pattern; it short-circuits.
  • .last-update-result.json: {"path":"native","outcome":"success","version_from":"2.1.183","version_to":"2.1.185","error_code":null}.

Expected vs actual

  • Expected: rename the running claude.exe aside (Windows permits renaming a running exe), copy the new version into place, then report success — or report failure if the swap didn't occur.
  • Actual: swap skipped, success reported, version unchanged, loops indefinitely.

Workaround

With no Claude process running, copy the already-staged binary into place manually:

Get-Process claude -ErrorAction SilentlyContinue | Stop-Process -Force
Copy-Item "$env:USERPROFILE\.local\share\claude\versions\2.1.185" "$env:USERPROFILE\.local\bin\claude.exe" -Force

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗