{"record":{"id":"0f7b17f45ae902d6","repo":"zeroclaw-labs/zeroclaw","slug":"downloaded-binary-too-small-bytes-likely-cor","errorCode":null,"errorMessage":"downloaded binary too small ({} bytes), likely corrupt","messagePattern":"downloaded binary too small \\((.+?) bytes\\), likely corrupt","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/commands/update.rs","lineNumber":703,"sourceCode":"            // file_type() does *not* follow symlinks, so a symlink shows up as\n            // is_symlink() — we drop it rather than dereferencing it.\n            let Ok(ft) = entry.file_type() else { continue };\n            let path = entry.path();\n            if ft.is_dir() {\n                stack.push(path);\n            } else if ft.is_file() {\n                out.push(path);\n            }\n            // Symlinks and any other special files are silently skipped.\n        }\n    }\n    out\n}\n\nasync fn validate_binary(path: &Path) -> Result<()> {\n    let meta = tokio::fs::metadata(path).await?;\n    if meta.len() < 1_000_000 {\n        bail!(\n            \"downloaded binary too small ({} bytes), likely corrupt\",\n            meta.len()\n        );\n    }\n\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\");","sourceCodeStart":685,"sourceCodeEnd":721,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/commands/update.rs#L685-L721","documentation":"validate_binary is a sanity gate the updater runs on the staged binary before installing it. Any staged file smaller than 1,000,000 bytes is rejected as 'likely corrupt' because real zeroclaw release binaries are multi-megabyte Rust builds. This catches truncated downloads and non-binary bodies before they can replace a working install.","triggerScenarios":"`zeroclaw update` after a download or unpack step that produced a short file: connection cut mid-transfer, a proxy/CDN error page saved as the asset body, a rate-limit response body, or disk-full during staging.","commonSituations":"Flaky networks, corporate proxies or MITM filters returning small HTML error bodies, GitHub rate limiting, low disk space in the temp/staging directory.","solutions":["Re-run `zeroclaw update`; transient truncation is the most common cause and a retry fixes it.","Compare the asset's published size on the release page with what lands on disk if the error repeats.","Check free space in the temp/staging directory and clear it if full.","If the published asset itself is tiny (mispackaged release), report it and pin the previous version."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let mut attempt = 0;\nloop {\n    attempt += 1;\n    match run_update().await {\n        Err(e) if e.to_string().contains(\"too small\") && attempt < 3 => continue, // re-download\n        other => break other,\n    }\n}","preventionTips":["Wrap unattended self-updates in a retry with backoff; truncated transfers are transient.","Monitor temp/staging disk space so extraction never writes short files.","Alert when the downloaded asset size differs sharply from the published size."],"tags":["update","download","truncated-file","corrupt-download"],"backgroundTag":"truncated-download","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}