-
Notifications
You must be signed in to change notification settings - Fork 1
bug: self-update fails on Windows — running binary is locked #354
Description
Bug
The dashboard "Update" button (POST /api/v1/system/update) returns HTTP 500 on Windows. The updater downloads the new archive but fails when attempting to os.Rename() over the running binary because Windows locks running executables.
Root Cause
In internal/updater/updater.go line 167:
if err := os.Rename(newBinaryPath, execPath); err != nil {On macOS/Linux, you can rename over a running binary (the old process keeps the deleted inode open). On Windows, the running .exe is locked by the OS — any attempt to overwrite or rename onto it fails with "Access is denied."
Observed Behavior
- Update check succeeds (finds newer version on GitHub)
- Archive downloads to
.mnemonic.update.zip - Binary extracts to
.mnemonic.update.tmp os.Rename(tmp, execPath)fails → 500 Internal Server Error- Temp files cleaned up (defer), leaving 0-byte artifacts in the filesystem watcher logs
Expected Behavior
Self-update should work on Windows, or fail gracefully with a clear message explaining the limitation.
Suggested Fix
Windows-specific update flow:
- Download and extract the new binary to
.mnemonic.update.tmp(this already works) - Rename the running binary to
.mnemonic.old(Windows allows renaming a locked file, just not overwriting it) - Rename
.mnemonic.update.tmp→mnemonic.exe - Restart the service (
sc stop mnemonic && sc start mnemonic) or use PID restart - On next startup, clean up
.mnemonic.old
Alternative: use the Windows MoveFileEx API with MOVEFILE_DELAY_UNTIL_REBOOT flag to schedule the replacement at next reboot, then restart the service.
Environment
- Windows 10 Pro 10.0.19045
- mnemonic v0.24.0 (service) attempting update to v0.33.0
- Binary running as Windows Service (SYSTEM account)