Hmbown/CodeWhale · error

The running executable path changed during the update; no…

Error message

The running executable path changed during the update; no further files were replaced. Run the intended executable again by its full path.

What it means

Before replacing files, the updater re-reads its own executable path and compares the SHA-256 of the bytes on disk to the hash recorded at update start. A mismatch means the file at the recorded path changed underneath the running process (it was replaced, edited, or a different binary now sits there), so the updater aborts having replaced nothing and tells the user to relaunch by full path.

Solutions

  1. Run the intended executable again by its full path (as the message says) so the identity is recomputed against the bytes actually on disk, then retry the update.
  2. Verify with `sha256sum <path>` which binary now occupies the path and reinstall the expected version if it is wrong.
  3. Prevent concurrent writers: do not run two updaters or installers against the same install directory at once.
  4. If it happens repeatedly, check antivirus/sync tools replacing the binary and exclude the install directory.
Defensive patterns

Strategy: try-catch

Validate before calling

let bytes = std::fs::read(&running_path)?;
let current = sha256_hex(&bytes);
if current != recorded_hash {
    eprintln!("binary at {running_path:?} changed since start; restart by full path before updating");
}

Try / catch

match run_update() {
    Err(e) if e.to_string().contains("running executable path changed") => {
        // no files were replaced; safely restart the intended binary by full path and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: validate_primary_update_identity, called at the start of run_update's swap phase, when sha256_hex(std::fs::read(identity.path)) differs from identity.file_hash.

Common situations: Another update/install overwrote the binary while this one ran; the user or a tool edited or replaced the executable mid-update; running from a copy that was subsequently overwritten; a previous aborted swap left a different binary at the path.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/9c58a0942daf71b9. Report an issue: GitHub.

Appendix: source

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

    let minor = ((device & 0xff) | ((device >> 12) & 0xfff00)) as u32;
    (major, minor)
}

fn validate_primary_update_identity(identity: &UpdateExecutableIdentity) -> Result<()> {
    #[cfg(target_os = "android")]
    {
        let fresh = android_loaded_executable_proof()?;
        if fresh != identity.android_proof {
            bail!(
                "Android loaded-image proof changed from {:?} to {:?}; refusing to replace the update target",
                identity.android_proof,
                fresh
            );
        }
    }
    let bytes = std::fs::read(&identity.path).context("failed to recheck updater binary")?;
    if sha256_hex(&bytes) != identity.file_hash {
        bail!(
            "The running executable path changed during the update; no further files were replaced. Run the intended executable again by its full path."
        );
    }
    Ok(())
}

/// Only the running binary and copies of those exact bytes are ours to update.
/// Command names alone do not establish ownership of an existing sibling.
fn validate_update_target(target: &Path, identity: &UpdateExecutableIdentity) -> Result<()> {
    if !InstallMethod::from_path(target).supports_self_update() || protected_update_path(target) {
        bail!(
            "Refusing to replace managed/system path {}.\n\n{GITHUB_MIGRATION_HELP}",
            target.display()
        );
    }
    let metadata = match std::fs::symlink_metadata(target) {
        Ok(metadata) => metadata,
        Err(error) if error.kind() == std::io::ErrorKind::NotFound && target != identity.path => {

View on GitHub (pinned to 73e0f67d83)