fix(updater/windows): fallback for cross-volume rename failures#5560
Conversation
On Windows, updater fails when replacing executables across different drives. When the helper attempts os.Rename, the system returns ERROR_NOT_SAME_DEVICE, causing repeated retries and eventual failure. This patch introduces a renameOrCopy fallback: - First try os.Rename as usual. - If it fails with cross-volume error, securely copy the file and delete the source. - Ensure cleanup of temporary files and partial writes. - Sweep leftover .old files once kernel releases locks. This fix allows portable binaries located on non-system drives (e.g. D:) to update successfully.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThis PR adds safe cross-volume file replacement to the Windows updater. A new ChangesWindows Cross-Volume File Replacement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@v3/pkg/updater/helper_windows.go`:
- Around line 47-64: renameOrCopy currently falls back to copyFileExec on any
os.Rename error; change it to only perform the copy-and-delete when the rename
error is the Windows cross-volume error (ERROR_NOT_SAME_DEVICE). Inspect the
returned error from os.Rename (likely *os.PathError), extract the underlying
syscall.Errno and compare it to syscall.ERROR_NOT_SAME_DEVICE (or numeric
17/0x11) and only call copyFileExec(src,dst) and os.Remove(src) in that case;
for any other error return the original os.Rename error unchanged. Ensure
references to renameOrCopy, copyFileExec, os.Rename, os.Remove and error
handling use the narrowed condition.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0bcd4729-a5bc-422f-a580-4a43d331080a
📒 Files selected for processing (1)
v3/pkg/updater/helper_windows.go
…DEVICE only Previously, renameOrCopy fell back to copy-and-delete on any os.Rename error, which would silently mask unrelated failures such as ACCESS_DENIED or a locked destination file. Unwrap the *os.LinkError returned by os.Rename on Windows and check the underlying syscall.Errno against ERROR_NOT_SAME_DEVICE (errno 17 / 0x11) before triggering the copy fallback. All other errors are returned as-is so callers see the real failure reason.
There was a problem hiding this comment.
Pull request overview
This PR improves the Windows updater helper’s ability to replace the running executable when the downloaded artifact is on a different drive/volume (where os.Rename fails with ERROR_NOT_SAME_DEVICE). It introduces a renameOrCopy fallback that attempts os.Rename first and, on cross-volume errors, copies the file and then removes the source.
Changes:
- Add
renameOrCopywith Windows cross-volume detection (ERROR_NOT_SAME_DEVICE) and a copy/delete fallback. - Add
copyFileExecto copy the executable with sync and partial-write cleanup on errors. - Update
replaceTargetto userenameOrCopyand slightly adjust error messaging/rollback behavior.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if err := copyFileExec(src, dst); err != nil { | ||
| return fmt.Errorf("cross-volume copy %s -> %s: %w", src, dst, err) | ||
| } | ||
|
|
||
| _ = os.Remove(src) | ||
| return nil |
| defer func() { | ||
| _ = out.Close() | ||
| if err != nil { | ||
| _ = os.Remove(dst) | ||
| } | ||
| }() |
| out, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode()) | ||
| if err != nil { | ||
| return err |
Bundles content from the failed alpha.99 release (tag pushed but no GitHub release created due to token misconfiguration) together with the alpha.100 cycle. Includes: - MacWebviewPreferences WKWebView extensions (#5549) - generate bindings "Access is denied" fix on Windows (#5561) - Linux frameless JS resize / scrollbar edge detection fix (#5368) - Windows updater cross-volume rename fallback (#5560)
On Windows, updater fails when replacing executables across different drives. When the helper attempts os.Rename, the system returns ERROR_NOT_SAME_DEVICE, causing repeated retries and eventual failure.
This patch introduces a renameOrCopy fallback:
This fix allows portable binaries located on non-system drives (e.g. D:) to update successfully.
Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
Type of change
Please select the option that is relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using
wails doctor.If you checked Linux, please specify the distro and version.
Test Configuration
Please paste the output of
wails doctor. If you are unable to run this command, please describe your environment in as much detail as possible.Checklist:
website/src/pages/changelog.mdxwith details of this PR (v3 changelog entries are added automatically)Summary by CodeRabbit