{"record":{"id":"19059ff9f903fe7d","repo":"zeroclaw-labs/zeroclaw","slug":"downloaded-file-too-small-to-be-a-valid-binary","errorCode":null,"errorMessage":"downloaded file too small to be a valid binary","messagePattern":"downloaded file too small to be a valid binary","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/commands/update.rs","lineNumber":748,"sourceCode":"}\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\n        .context(\"failed to read binary header\")?;\n\n    if header.len() < 20 {\n        bail!(\"downloaded file too small to be a valid binary\");\n    }\n\n    let binary_arch = detect_arch_from_header(&header);\n    let host_arch = host_architecture();\n\n    if let (Some(bin), Some(host)) = (binary_arch, host_arch)\n        && bin != host\n    {\n        bail!(\n            \"architecture mismatch: downloaded binary is {bin} but this host is {host} — \\\n             the release asset may be mispackaged\"\n        );\n    }\n\n    Ok(())\n}\n\nfn detect_arch_from_header(header: &[u8]) -> Option<&'static str> {","sourceCodeStart":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/commands/update.rs#L730-L766","documentation":"check_binary_arch opens the staged file and reads up to 4096 bytes of its header to detect the machine type (ELF/PE/Mach-O). Fewer than 20 bytes were read, which is below the minimum needed to parse any executable format, so the file is judged not to be a valid binary at all.","triggerScenarios":"`zeroclaw update` when the staged binary path exists but is empty or nearly empty: extraction wrote a zero-length file (interrupted unpack, disk full), or a placeholder/empty body survived the earlier size checks in a hand-crafted flow.","commonSituations":"Interrupted or crashed unpack step; temp filesystem full during extraction; testing harnesses that stage fake files into the update pipeline.","solutions":["Re-run `zeroclaw update` to redo download and unpack from scratch.","Check free space on the volume holding the temp/staging directory.","Inspect the staged file size if you have a custom harness feeding the pipeline; anything under 20 bytes is not an executable.","If it reproduces on a stock install, report it with OS and disk details."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match run_update().await {\n    Err(e) if e.to_string().contains(\"too small to be a valid binary\") => {\n        // empty staged file: re-run the full download+unpack\n    }\n    other => other,\n}","preventionTips":["Ensure the temp directory used for staging is writable and not full before updates.","Avoid killing update processes mid-unpack; let the sweep/resume logic or a fresh run handle residue.","In test harnesses that feed the pipeline, never stage files shorter than a valid executable header."],"tags":["update","binary-validation","empty-file","corrupt-download"],"backgroundTag":"invalid-executable-format","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}