Hmbown/CodeWhale · error · anyhow::Error

Android {authority} reported deleted loaded image `{}`

Error message

Android {authority} reported deleted loaded image `{}`

What it means

A reported loaded-image path ends with ' (deleted)', the kernel suffix marking that the mapped file was unlinked after the process started. Writing an update to a deleted path is unsafe/meaningless, so the updater refuses and asks you to restart or reinstall first.

Source

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

    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() {
        bail!(
            "Android {authority} reported non-absolute loaded-image path `{}`",
            path.display()
        );
    }
    if path.to_string_lossy().ends_with(" (deleted)") {
        bail!(
            "Android {authority} reported deleted loaded image `{}`",
            path.display()
        );
    }
    if is_android_linker_name(path) {
        bail!(
            "Android {authority} identifies runtime linker `{}`; refusing to use the linker as an update target",
            path.display()
        );
    }
    Ok(())
}

#[cfg(any(target_os = "android", all(test, unix)))]
fn validate_android_mapping_identity(
    mapping: &AndroidImageMapping,
    candidate: &Path,
) -> Result<()> {

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Restart the CLI so the process maps the new file, then run update again
  2. If the binary is actually gone, reinstall it with the documented installer
  3. Avoid cleaning/replacing the install directory while the CLI is running
Defensive patterns

Strategy: validation

Validate before calling

fn current_image_is_deleted() -> bool {
    std::fs::read_link("/proc/self/exe")
        .map(|p| p.to_string_lossy().ends_with(" (deleted)"))
        .unwrap_or(false)
}

// run before self-update:
if current_image_is_deleted() {
    eprintln!("running image was replaced; restart the process before updating");
}

Try / catch

Catch the error and instruct a restart: after the process re-execs onto the new file, the '(deleted)' suffix disappears and update can proceed.

Prevention

When it happens

Trigger: Android self-update after the binary file was replaced or removed while the process keeps running: a previous in-place self-update already swapped the file, or a package manager/cleanup tool unlinked it.

Common situations: Re-running update in a session whose binary was already replaced by an earlier update; installers that remove-then-rename during upgrade.

Related errors


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