Hmbown/CodeWhale · error
Android loaded image
Error message
Android loaded image `{}` is not an executable regular file; refusing to select an update target What it means
After both path authorities agree and the path is not the linker, the updater stats the resolved file to confirm it is an executable regular file before selecting it as the update target. If it is missing, a directory, a symlink to nothing, or lacks the execute bit, the updater refuses — replacing such a path would not yield a runnable updated binary.
Solutions
- Re-install the binary freshly so a live executable file exists at the path, then re-run the update.
- Restore the execute bit: `chmod 755 <path-to-binary>`, then retry.
- Verify with `ls -l` and `stat` that the resolved path from the error message exists, is a regular file, and is executable.
- If the binary was replaced underneath the running process, kill the old process and start the newly installed binary by its full path before updating again.
Example fix
// before cp codewhale $PREFIX/bin/ && $PREFIX/bin/codewhale update # exec bit lost // after install -m 755 codewhale $PREFIX/bin/codewhale && $PREFIX/bin/codewhale update
Defensive patterns
Strategy: validation
Validate before calling
use std::os::unix::fs::PermissionsExt;
fn is_executable_file(p: &std::path::Path) -> bool {
std::fs::metadata(p)
.map(|m| m.is_file() && m.permissions().mode() & 0o111 != 0)
.unwrap_or(false)
}
if !is_executable_file(&target) { /* reinstall or chmod before updating */ } Try / catch
match run_update() {
Err(e) if e.to_string().contains("not an executable regular file") => {
// prompt: reinstall the release, then retry
}
other => other?,
} Prevention
- Always copy releases with the executable bit set (install -m 755).
- Never delete or replace a binary that a running process was started from.
- Verify the target exists and is executable before triggering self-update.
- Exclude install directories from cleaner apps / aggressive package managers.
When it happens
Trigger: android_loaded_executable_proof when is_executable_file() returns false for the resolved mapping path (file deleted after mapping, permissions stripped, path now points at a non-regular file).
Common situations: The binary was deleted or replaced on disk while the process still ran (maps refers to the unlinked inode path); a package manager or cleaner app removed the app's native lib/binary; the executable bit was lost after copying the binary manually (common when extracting from an archive on Android).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- The system/package executable was not changed.
- Android identifies runtime linker ` `; refusing to use the…
- Android reported deleted loaded image
- Android reported non-absolute loaded-image path
- Android dladdr could not locate the updater's loaded image
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/17eb099e5ad1ff51.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/update.rs:462
"failed to canonicalize Android loaded-image mapping {}",
mapping.path.display()
)
})?;
if resolved_dladdr != resolved_mapping {
bail!(
"Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}",
resolved_dladdr.display(),
resolved_mapping.display()
);
}
if is_android_linker_name(&resolved_mapping) {
bail!(
"Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target",
resolved_mapping.display()
);
}
if !is_executable_file(&resolved_mapping) {
bail!(
"Android loaded image `{}` is not an executable regular file; refusing to select an update target",
resolved_mapping.display()
);
}
validate_android_mapping_identity(&mapping, &resolved_mapping)?;
Ok(AndroidExecutableProof {
path: resolved_mapping,
device_major: mapping.device_major,
device_minor: mapping.device_minor,
inode: mapping.inode,
proof_kind: AndroidExecutableProofKind::DladdrAndProcMaps,
})
}
#[cfg(any(target_os = "android", all(test, unix)))]
fn validate_android_reported_path(authority: &str, path: &Path) -> Result<()> {
if !path.is_absolute() {View on GitHub (pinned to 73e0f67d83)