Hmbown/CodeWhale · error

Android reported deleted loaded image

Error message

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

What it means

Linux appends " (deleted)" to the path in /proc/self/maps when the mapped file has been unlinked. A deleted loaded image means the on-disk file the process runs from no longer exists at that name, so there is nothing legitimate to replace — updating would target a name no longer backed by the running inode. The updater detects the suffix and refuses.

Solutions

  1. Kill the running process and start the newly installed binary by its full path; self-update only from a binary that still exists on disk.
  2. Reinstall the current release so a live file exists at the expected path, then run the update from that fresh process.
  3. Avoid deleting/renaming the updater binary while an update from it is in flight.
  4. If this recurs after every update, check for another agent (sync client, antivirus, package manager) removing the binary mid-run.
Defensive patterns

Strategy: validation

Validate before calling

fn path_is_live(p: &std::path::Path) -> bool {
    let s = p.to_string_lossy();
    !s.ends_with(" (deleted)") && p.exists()
}
if !path_is_live(&reported_path) { /* restart from a freshly installed binary before updating */ }

Try / catch

match run_update() {
    Err(e) if e.to_string().contains("reported deleted loaded image") => {
        // instruct user: restart the newly installed binary by full path, retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: validate_android_reported_path, called from android_loaded_executable_proof_report, when either the dladdr path or the maps row path ends with " (deleted)".

Common situations: Something replaced or deleted the binary while the old process was still running (e.g. a prior partial update, an `rm` + reinstall, or a package manager swap); the updater itself previously swapped files without restarting the process.

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


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

Appendix: source

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

    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 73e0f67d83)