Hmbown/CodeWhale · error · anyhow::Error

failed to install new binary at {}: {}

Error message

failed to install new binary at {}: {}

What it means

During self-update on Windows, after the current executable was moved aside to a backup, atomically persisting the new temporary binary onto the target path failed. The original binary is restored from the backup, so the installation is rolled back rather than left half-done; the underlying persist error is appended to the message.

Source

Thrown at crates/cli/src/update.rs:1778

    #[cfg(windows)]
    {
        let backup = backup_path_for(target);
        if target.exists() {
            std::fs::rename(target, &backup).with_context(|| {
                format!(
                    "failed to move current executable {} to {}",
                    target.display(),
                    backup.display()
                )
            })?;
        }

        if let Err(err) = tmp.persist(target) {
            if backup.exists() {
                let _ = std::fs::rename(&backup, target);
            }
            bail!(
                "failed to install new binary at {}: {}",
                target.display(),
                err.error
            );
        }

        let _ = std::fs::remove_file(&backup);
    }

    #[cfg(not(windows))]
    {
        tmp.persist(target)
            .map_err(|err| err.error)
            .with_context(|| format!("failed to rename temp file to {}", target.display()))?;
    }

    Ok(())
}

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Close all running Codewhale processes (TUI sessions, background agents) and retry the update
  2. Run the update from a shell with write access to the install directory (elevate if installed under Program Files)
  3. Read the appended persist error: 'Access is denied' → permissions/AV lock; different-drive error → set TMP to the same volume as the target
  4. Add an AV exclusion for the Codewhale install directory if scans repeatedly lock the binary
  5. Fall back to a manual install: download the asset, verify it, and replace the binary while Codewhale is not running

Example fix

# before
$ codewhale update
failed to install new binary at C:\Program Files\codewhale\codewhale.exe: Access is denied (os error 5)

# after
# close all codewhale.exe processes, then from an elevated shell
$ codewhale update
Defensive patterns

Strategy: retry

Validate before calling

// Before updating, confirm the install target is writable and not in use:
use std::fs::OpenOptions;
let probe = OpenOptions::new().write(true).open(target).is_ok();
// On Windows also ensure no codewhale.exe processes remain:
let busy = std::process::Command::new("tasklist")
    .args(["/FI", "IMAGENAME eq codewhale.exe"]) 
    .output().map(|o| String::from_utf8_lossy(&o.stdout).contains("codewhale.exe"))
    .unwrap_or(false);
if !probe || busy { /* defer the update */ }

Try / catch

match install_binary(&tmp, target) {
    Ok(()) => Ok(()),
    Err(e) if e.to_string().contains("failed to install new binary") => {
        // updater already restored the backup; tell user to close processes,
        // gain write access, then retry once
        report_and_retry_after_user_action(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: tempfile persist(target) fails: target directory not writable (installed under Program Files without elevation), the old binary is still running/locked (running process holds a write lock on Windows), antivirus quarantines or locks the new file, or the temp dir and target are on different volumes (EXDEV-style persist failure).

Common situations: CLI installed to a protected directory and updated without admin rights; a second Codewhale instance (TUI session, background agent) still running during update; over-aggressive AV scanning freshly written executables; TMP redirected to a different drive.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/929331cac2399ac0. Report an issue: GitHub.