Hmbown/CodeWhale · error
Refusing to replace : its bytes differ from the running…
Error message
Refusing to replace {}: its bytes differ from the running executable. This may be another installation or an unrelated command. No command is removed automatically.
{GITHUB_MIGRATION_HELP} What it means
Before replacing a file, the updater hashes it (sha256) and compares against the running executable's hash (identity.file_hash). If the bytes differ, the target is some other installation or an unrelated command that merely shares the name, so the updater refuses — no command is ever removed automatically.
Solutions
- Identify which copy you actually use (`which -a codewhale`, compare hashes) and run update from the binary you want updated.
- Remove the foreign/stale binary manually after confirming it is not yours; the updater will not delete it for you.
- Reinstall from the official installer so only one managed copy exists, then update.
Example fix
// before: stale v0.1 binary next to running v0.2 refuses replacement $ sha256sum ~/.local/bin/codewhale # differs from running binary // after: delete the stale copy yourself, then update $ rm ~/.local/bin/codewhale-old && codewhale update
Defensive patterns
Strategy: validation
Validate before calling
use sha2::{Digest, Sha256};
fn matches_running_binary(path: &std::path::Path, expected: &str) -> bool {
std::fs::read(path).map(|b| Sha256::digest(&b) == *expected.as_bytes()).unwrap_or(false)
} Prevention
- Maintain exactly one codewhale installation; remove duplicates before updating
- Don't rename unrelated binaries to `codewhale` in the same bin directory
- Compare `sha256sum` of installed copies against the running binary when in doubt
When it happens
Trigger: validate_update_target reads the target file and its sha256_hex does not equal identity.file_hash; raised for stale copies from older versions, different builds, or unrelated binaries placed next to the real one.
Common situations: Two independent installations of codewhale exist (one built from source, one downloaded); a different tool was named `codewhale` in the same bin dir; the binary was modified/patched after install.
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
- Refusing to replace managed/system path
- Refusing to replace : the update target is not a regular…
- Agent continuation target is outside the active session
- Android identifies runtime linker ` `; refusing to use the…
- Android reported deleted loaded image
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/37be56bd958ff2c9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/update.rs:591
Ok(metadata) => metadata,
Err(error) if error.kind() == std::io::ErrorKind::NotFound && target != identity.path => {
return Ok(());
}
Err(error) => {
return Err(error)
.with_context(|| format!("failed to inspect update target {}", target.display()));
}
};
if !metadata.is_file() || metadata.is_symlink() {
bail!(
"Refusing to replace {}: the update target is not a regular file.\n\n{GITHUB_MIGRATION_HELP}",
target.display()
);
}
let bytes = std::fs::read(target)
.with_context(|| format!("failed to identify update target {}", target.display()))?;
if sha256_hex(&bytes) != identity.file_hash {
bail!(
"Refusing to replace {}: its bytes differ from the running executable. This may be another installation or an unrelated command. No command is removed automatically.\n\n{GITHUB_MIGRATION_HELP}",
target.display()
);
}
Ok(())
}
fn protected_update_path(path: &Path) -> bool {
[
"/usr/bin",
"/usr/sbin",
"/bin",
"/sbin",
"/nix/store",
"/gnu/store",
]
.iter()
.any(|prefix| path.starts_with(prefix))View on GitHub (pinned to 73e0f67d83)