{"record":{"id":"edaac3d576a0615d","repo":"zeroclaw-labs/zeroclaw","slug":"downloaded-binary-does-not-appear-to-be-zeroclaw","errorCode":null,"errorMessage":"downloaded binary does not appear to be zeroclaw","messagePattern":"downloaded binary does not appear to be zeroclaw","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/commands/update.rs","lineNumber":726,"sourceCode":"\n    // Check binary architecture before attempting execution so we can give\n    // a clear diagnostic instead of the opaque \"Exec format error (os error 8)\".\n    check_binary_arch(path).await?;\n\n    // Quick check: try running --version\n    let output = tokio::process::Command::new(path)\n        .arg(\"--version\")\n        .output()\n        .await\n        .context(\"cannot execute downloaded binary\")?;\n\n    if !output.status.success() {\n        bail!(\"downloaded binary --version check failed\");\n    }\n\n    let stdout = String::from_utf8_lossy(&output.stdout);\n    if !stdout.contains(\"zeroclaw\") {\n        bail!(\"downloaded binary does not appear to be zeroclaw\");\n    }\n\n    Ok(())\n}\n\nasync fn check_binary_arch(path: &Path) -> Result<()> {\n    use tokio::io::AsyncReadExt;\n\n    // Read only the header — enough to cover a PE file's DOS stub and reach the\n    // COFF machine field pointed to by `e_lfanew` (well under 4 KiB in practice)\n    // — instead of pulling the whole multi-megabyte binary into memory.\n    let mut header = Vec::new();\n    tokio::fs::File::open(path)\n        .await\n        .context(\"failed to open binary to read header\")?\n        .take(4096)\n        .read_to_end(&mut header)\n        .await","sourceCodeStart":708,"sourceCodeEnd":744,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/commands/update.rs#L708-L744","documentation":"The final check in validate_binary runs the downloaded binary with --version and requires the string 'zeroclaw' to appear in stdout. Exit status was zero but the output did not identify itself as zeroclaw, so the updater refuses to install a file that is probably the wrong executable.","triggerScenarios":"`zeroclaw update` when the downloaded archive contains a different (working) binary under the expected name: mispackaged release where another project's binary was shipped, a mirror or cache serving a substituted file, or a wrapper/renamed binary inside the archive.","commonSituations":"Release packaging scripts copying the wrong build artifact; artifact-name collisions in CI caches; a future version whose --version output stops containing the literal product name (regression).","solutions":["Run the downloaded binary's --version manually and compare its output with a known zeroclaw release.","Check the release page: if the asset is mispackaged, report it and use the previous version.","Clear any HTTP cache/mirror between you and the download URL and retry.","If you maintain the release: ensure --version output keeps containing 'zeroclaw', since the updater relies on it."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match run_update().await {\n    Err(e) if e.to_string().contains(\"does not appear to be zeroclaw\") => {\n        // wrong executable shipped: keep current install, report release\n    }\n    other => other,\n}","preventionTips":["Publish releases from a pipeline that verifies the packaged binary's --version output, not just build success.","Bypass caches/mirrors when fetching release assets for update automation.","Keep the literal 'zeroclaw' token in --version output; the updater depends on it."],"tags":["update","binary-validation","wrong-binary","release-artifact"],"backgroundTag":"release-asset-mismatch","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}