# [BUG] [Windows] Auto-updater stuck in reinstall loop: daemon self-restarts on mtime change and reinstalls the same version repeatedly, flashing cmd windows every few minutes
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
On Windows, the Claude Code auto-updater has entered a self-perpetuating loop that repeatedly runs npm install -g @anthropic-ai/claude-code@<latest> for a version that is already installed. Each reinstall rewrites claude.exe, changing its mtime; the daemon's binary-watcher interprets the mtime change as a new upgrade and self-restarts, which re-arms the update check, which reinstalls again. The visible symptom is a black cmd.exe/node.exe console window flashing on screen every 1-3 minutes, continuously, for over 24 hours.
The version never advances because it is already the latest - the loop is driven purely by mtime churn, not by an actual version difference.
Environment
- OS: Windows 11 Home (10.0.26200)
- Claude Code: 2.1.158 (installed via npm global)
- Latest published: 2.1.158 (identical - already up to date)
- Node: v22.19.0
- npm: 10.9.3
- npm global prefix: C:\Users\<user>\AppData\Roaming\npm (confirmed writable)
- Concurrent claude.exe sessions: ~33 (long-standing setup, not new)
Symptom
A black console window briefly appears and disappears every couple of minutes. Process tracing shows the spawned command is always one of:
cmd /c "npm view @anthropic-ai/claude-code@latest version --prefer-online"
cmd /c "npm install -g @anthropic-ai/claude-code@2.1.158"
Every such process is parented to a claude.exe session.
Impact
- Constant flashing console windows (UX/annoyance, steals focus on some configs).
- Continuous redundant npm installs and daemon restarts (wasted CPU/network/disk churn).
- Not a failed update and not a permissions problem - the install succeeds every time; there is simply no terminal/"already current" state.
Suggested fixes
- Skip
npm installwhen the installed version already equals the resolved latest. - Use a content hash (or version string) instead of mtime to decide whether the binary actually changed.
- Add an "already current" short-circuit so a no-op reinstall cannot re-arm the watcher.
Workaround
Setting DISABLE_AUTOUPDATER=1 stops the loop (already on latest, so nothing lost), but this disables automatic updates entirely, which is not desirable as a permanent fix.
What Should Happen?
Expected behavior
- The updater should treat "already on latest" as a no-op and not reinstall.
- The daemon's "binary changed" detection should key off version/content hash rather than mtime, so an identical reinstall does not trigger a self-restart-for-upgrade.
Error Messages/Logs
Steps to Reproduce
Root cause (evidence from ~/.claude/daemon.log)
The daemon log shows a tight repeating cycle. Representative excerpt:
[2026-05-30T00:49:31Z] [supervisor] binary at ...\claude.exe changed (mtime changed) - self-restarting for upgrade
[2026-05-30T00:49:31Z] [supervisor] shutting down
[2026-05-30T00:49:33Z] [supervisor] daemon start version=2.1.158
[2026-05-30T00:52:34Z] [supervisor] binary at ...\claude.exe changed (mtime changed) - self-restarting for upgrade
[2026-05-30T00:52:34Z] [supervisor] shutting down
[2026-05-30T00:52:37Z] [supervisor] daemon start version=2.1.158
... repeats indefinitely, always landing on the same version 2.1.158
The loop:
- A session's auto-updater runs
npm install -g @anthropic-ai/claude-code@latest. - The reinstall rewrites claude.exe - same version, new mtime.
- The daemon's binary-watcher sees the mtime change and self-restarts "for upgrade".
- On restart the update check re-arms and reinstalls again -> back to step 1.
It never converges because the reinstall changes the file mtime even though the contents/version are unchanged.
Contributing factor: multi-daemon lock races
With multiple concurrent sessions, the log also shows daemons racing over the singleton lock, e.g.:
[supervisor] another daemon won the lock race (pid=...) - exiting
[supervisor] another daemon is already running (pid=..., version=2.1.158, origin=transient ...). Stop it with `taskkill /PID ...`, then retry.
When one session reinstalls and bumps the binary mtime, it appears to trip the "binary changed" self-restart in the other sessions' daemons too, so they each re-check/reinstall. This amplifies the loop across the session fleet.
Timeline / trigger
- daemon.log begins 2026-05-29T23:53 running version 2.1.157.
- First "self-restarting for upgrade" fires 3 minutes later at 2026-05-29T23:56.
- 45 restart events logged between 2026-05-29T23:56 and 2026-05-31T01:17 (and ongoing).
- This coincides with a burst of releases (2.1.153 on 27 May -> 2.1.158 on 30 May). The rapid upgrades appear to have kicked off the mtime-churn loop, which then sustains itself even after reaching the latest version.
The session count is long-standing and unchanged; the new variable was the release burst, not the number of sessions.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.158 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗