Hmbown/CodeWhale · error · anyhow::Error
no /proc/self/maps row contains the updater marker
Error message
no /proc/self/maps row contains the updater marker
What it means
On Android the updater must prove which on-disk file the running executable was loaded from. It scans /proc/self/maps for a row whose [start, end) range contains a marker address taken from the CLI's own code image. This error means the scan finished without any row covering the marker, so the loaded image could not be attributed to a file and self-update is refused.
Source
Thrown at crates/cli/src/update.rs:374
.context("loaded-image mapping has an invalid device minor number")?;
if path.is_empty() {
bail!("loaded-image mapping for updater marker has no pathname");
}
let mapping = AndroidImageMapping {
start,
end,
device_major,
device_minor,
inode,
path: PathBuf::from(path),
};
if matching.replace(mapping).is_some() {
bail!("multiple /proc/self/maps rows contain the updater marker");
}
}
matching.ok_or_else(|| anyhow!("no /proc/self/maps row contains the updater marker"))
}
#[cfg(all(test, unix))]
fn resolve_android_loaded_executable_report(
maps: &str,
marker: u64,
dladdr_path: &Path,
) -> Result<PathBuf> {
Ok(android_loaded_executable_proof_report(maps, marker, dladdr_path)?.path)
}
#[cfg(any(target_os = "android", all(test, unix)))]
fn android_loaded_executable_proof_report(
maps: &str,
marker: u64,
dladdr_path: &Path,
) -> Result<AndroidExecutableProof> {
let mapping = parse_android_image_mapping(maps, marker)?;View on GitHub (pinned to 8880682c63)
Solutions
- Inspect the live process (adb shell cat /proc/<pid>/maps): if the executable rows have no pathname, that Android build hides them and self-update from that location is unsupported; install the binary on a mapped path instead
- If this is a test fixture, add a row like '7f0000000000-7f0000001000 r-xp 00000000 fd:01 1337 /data/local/tmp/codewhale' whose range covers the marker, has executable permission, nonzero inode, and a pathname
- Update to a newer Codewhale build: the Android proof logic also consults dladdr as a second authority and may succeed where the maps scan alone cannot
- If the process runs from memfd or an interpreter, launch the real binary file so it gets a file-backed mapping
Example fix
// test fixture: before (marker 0x7f0000000042 is not covered) let maps = "00000000-00010000 r-xp 00000000 fd:01 10 /system/bin/linker64\n"; // after: add a row that covers the marker let maps = "00000000-00010000 r-xp 00000000 fd:01 10 /system/bin/linker64\n\n7f0000000000-7f0000001000 r-xp 00000000 fd:01 1337 /data/local/tmp/codewhale\n";
Defensive patterns
Strategy: try-catch
Validate before calling
// Before invoking the proof path, verify the maps text covers the marker:
fn maps_cover_marker(maps: &str, marker: u64) -> bool {
maps.lines().any(|line| {
let mut fields = line.split_whitespace();
let range = match fields.next() { Some(r) => r, None => return false };
let (s, e) = match range.split_once('-') { Some(p) => p, None => return false };
match (u64::from_str_radix(s, 16), u64::from_str_radix(e, 16)) {
(Ok(s), Ok(e)) => s <= marker && marker < e,
_ => false,
}
})
} Try / catch
Treat the Err as 'cannot self-update on this Android layout': report to the user and skip replacement rather than retrying. The maps/marker relationship is stable for the life of the process, so retries cannot succeed.
Prevention
- Run the CLI from a file-backed executable with a pathname-mapped mapping on Android instead of memfd or interpreter loading
- Keep test maps fixtures synchronized with the marker address constant
When it happens
Trigger: parse_android_image_mapping runs with the /proc/self/maps text and the marker address; it fires when no row satisfies start <= marker < end: the maps snapshot does not describe this process, the image is only in anonymous/JIT mappings (no pathname), or a test passes fixture maps whose ranges all miss the marker.
Common situations: Android 10+ replaces app-data executable paths in /proc/self/maps with unnamed mappings; running under instrumentation (gdbserver, wrap.sh) or from an interpreter such as app_process; emulators with unusual layouts; unit tests with hand-written maps fixtures that forget to cover the marker address.
Related errors
- self-update is not supported on HarmonyOS/OpenHarmony yet
- failed to fetch {description} from {url}: HTTP {status} {bod
- download failed with HTTP {status}: {body}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/3e1557602abb5208.
Report an issue: GitHub.