zeroclaw-labs/zeroclaw · error · anyhow::Error

archive does not contain a '{target_name}' binary

Error message

archive does not contain a '{target_name}' binary

What it means

After downloading and checksum-verifying the release .tar.gz, the updater unpacks it into a staging directory and locate_main_binary (via walk_files) scans only regular files, skipping directories and symlinks, for the main binary named 'zeroclaw' (zeroclaw.exe on Windows). This error means no such regular file exists anywhere in the staged tree, so there is nothing to install.

Source

Thrown at src/commands/update.rs:671

/// Find the freshly unpacked main binary in `staging`.
///
/// Walks the staged tree looking for a `zeroclaw` (or `zeroclaw.exe`) file. The
/// release archive is flat — the binary sits at the staging root — but we walk
/// in case a future archive layout introduces a wrapper directory (e.g.
/// `zeroclaw-v0.9/zeroclaw.exe`, which Windows zip tooling sometimes produces).
fn locate_main_binary(staging: &Path) -> Result<PathBuf> {
    let target_name = main_binary_name();
    for entry in walk_files(staging) {
        if entry
            .file_name()
            .and_then(|n| n.to_str())
            .map(|n| n == target_name)
            .unwrap_or(false)
        {
            return Ok(entry);
        }
    }
    bail!("archive does not contain a '{target_name}' binary")
}

/// Collect all **regular file** paths under `root`, skipping directories and
/// symlinks. Used by `locate_main_binary` so it sees the same view of the
/// staged tree as `install_companion_artifacts`.
fn walk_files(root: &Path) -> Vec<PathBuf> {
    let mut out = Vec::new();
    let mut stack = vec![root.to_path_buf()];
    while let Some(dir) = stack.pop() {
        let Ok(entries) = std::fs::read_dir(&dir) else {
            continue;
        };
        for entry in entries.flatten() {
            // file_type() does *not* follow symlinks, so a symlink shows up as
            // is_symlink() — we drop it rather than dereferencing it.
            let Ok(ft) = entry.file_type() else { continue };
            let path = entry.path();
            if ft.is_dir() {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Download the same release asset manually and list its contents: `tar -tzf zeroclaw-*.tar.gz | head -30` to confirm whether a top-level 'zeroclaw' regular file exists.
  2. If the archive is wrong, report the mispackaged release and update to the nearest fixed version.
  3. If the release layout changed, update zeroclaw to the version that supports the new layout (or install that release manually from the release page).
  4. As a workaround, install the binary from the archive by hand into the current install directory.
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
# pre-flight before `zeroclaw update`: archive must contain the main binary
url="https://github.com/zeroclaw/zeroclaw/releases/download/vX/zeroclaw-x86_64-linux.tar.gz"
if ! curl -fsSL "$url" | tar -tz | grep -qx 'zeroclaw'; then
  echo "release archive lacks the zeroclaw binary" >&2; exit 1
fi

Try / catch

match run_update().await {
    Err(e) if e.to_string().contains("does not contain a '") => {
        // mispackaged archive: stop, report the release, do not retry
    }
    other => other,
}

Prevention

When it happens

Trigger: `zeroclaw update` completes download and unpack, but the archive contains no regular file whose name is 'zeroclaw': the binary is missing, shipped only as a symlink (walk_files skips symlinks), nested under a differently-named path in a changed release layout, or the wrong asset (e.g. a source tarball) was downloaded.

Common situations: Mispackaged release where the packaging script renamed or omitted the top-level binary; release layout change (versioned top-level directory) that the running zeroclaw version does not understand; asset-name to content mismatch on the release.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/31333533aeda8b23. Report an issue: GitHub.