hasura/graphql-engine · error
rename exe to old: %w
Error message
rename exe to old: %w
What it means
During ApplyUpdate's atomic swap, os.Rename(exe, oldExe) — renaming the current binary to '<exe>.old' — failed (cli/update/update.go:164). This happens before the new binary is moved into place, so the installation is still intact; typical causes are lacking write permission on the directory or the running executable being immutable/locked.
Source
Thrown at cli/update/update.go:164
return errors.E(op, fmt.Errorf("download asset: %w", err))
}
// get the downloaded binary name and build the absolute path
newExe := asset.Name()
// build name and absolute path for saving old binary
oldExeName := "." + exeName + ".old"
oldExe := filepath.Join(exePath, oldExeName)
// delete any existing old binary file - this is necessary on Windows for two reasons:
// 1. after a successful update, Windows can't remove the .old file because the process is still running
// 2. windows rename operations fail if the destination file already exists
_ = os.Remove(oldExe)
// rename the current binary as old binary
err = os.Rename(exe, oldExe)
if err != nil {
return errors.E(op, fmt.Errorf("rename exe to old: %w", err))
}
// rename the new binary as the current binary
err = os.Rename(newExe, exe)
if err != nil {
// rename unsuccessful
//
// The filesystem is now in a bad state. We have successfully
// moved the existing binary to a new location, but we couldn't move the new
// binary to take its place. That means there is no file where the current executable binary
// used to be!
// Try to rollback by restoring the old binary to its original path.
rerr := os.Rename(oldExe, exe)
if rerr != nil {
// rolling back failed, ask user to re-install cli
return errors.E(op, fmt.Errorf(
"rename old to exe: inconsistent state, re-install cli: %w",
rerr))View on GitHub (pinned to 724551b9ae)
Solutions
- Ensure write permission on the directory containing the binary (or rerun the update with elevated privileges on macOS/Windows).
- Delete a stale '<exe>.old' if it exists and the rename reports a conflict (preparation normally removes it, but check manually).
- Disable/exclude the CLI binary from antivirus locking on Windows.
- Avoid installing the binary on network filesystems where rename semantics are unreliable.
Example fix
# before $ cli update # error: rename exe to old: permission denied # after (unix) $ sudo chown $(whoami) /usr/local/bin/cli $ cli update
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(exe)
if werr := testWritable(dir); werr != nil {
return fmt.Errorf("cannot update: %w (try adjusting permissions)", werr)
} Try / catch
if err := update.ApplyUpdate(v); err != nil {
if strings.Contains(err.Error(), "rename exe to old") {
// installation still intact, safe to keep using current version
log.Printf("update aborted before swap: %v", err)
}
return err
} Prevention
- Own the install directory (chown) or use a user-local install prefix.
- Exclude the binary from antivirus real-time locks on Windows.
- Remove stale .old files before updating.
When it happens
Trigger: ApplyUpdate where the install directory is not writable by the current user, another process holds a mandatory lock on the binary, or the filesystem does not allow renaming a running executable (some NFS/Windows configurations).
Common situations: CLI installed in /usr/local/bin and update run without sudo; Windows antivirus scanning the exe at the moment of rename; binary on a read-only or network mount.
Related errors
- could not rename/copy file from %q to %q: %w
- writing metadata to file: %w
- error getting directory details: %w
- write file: %w
- cannot create global config directory: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/822429007165647a.
Report an issue: GitHub.