Skip to content

bug: self-update fails on Windows — running binary is locked #354

@jkbennitt

Description

@jkbennitt

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

  1. Update check succeeds (finds newer version on GitHub)
  2. Archive downloads to .mnemonic.update.zip
  3. Binary extracts to .mnemonic.update.tmp
  4. os.Rename(tmp, execPath) fails → 500 Internal Server Error
  5. 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:

  1. Download and extract the new binary to .mnemonic.update.tmp (this already works)
  2. Rename the running binary to .mnemonic.old (Windows allows renaming a locked file, just not overwriting it)
  3. Rename .mnemonic.update.tmpmnemonic.exe
  4. Restart the service (sc stop mnemonic && sc start mnemonic) or use PID restart
  5. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions