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

smoke test: updated binary returned non-zero exit code

Error message

smoke test: updated binary returned non-zero exit code

What it means

After swapping the new binary into place, the updater smoke-tests it by running `<installed-binary> --version`. A non-zero exit aborts with this error; the updater has rollback machinery (rollback_binary restoring the backup, at least on Windows) and skips companion-artifact installation on failure. This check catches an update that is broken only in its final installed context.

Source

Thrown at src/commands/update.rs:984

            Err(_) => {
                // Can't tell what it is; try file first, then dir.
                if tokio::fs::remove_file(&path).await.is_err() {
                    let _ = tokio::fs::remove_dir_all(&path).await;
                }
            }
        }
    }
}

async fn smoke_test(binary: &Path) -> Result<()> {
    let output = tokio::process::Command::new(binary)
        .arg("--version")
        .output()
        .await
        .context("smoke test: cannot execute updated binary")?;

    if !output.status.success() {
        bail!("smoke test: updated binary returned non-zero exit code");
    }

    Ok(())
}

/// Install every artifact in `staging` other than the main binary onto the
/// running install: the `web/dist` dashboard bundle and any other top-level
/// files (e.g. the `zerocode` companion).
///
/// Best-effort by design — the `zeroclaw` binary has already been swapped and
/// smoke-tested. A failure here (e.g. an unwritable data directory) is logged
/// and swallowed rather than failing or rolling back an otherwise-good update.
async fn install_companion_artifacts(
    staging: &Path,
    current_exe: &Path,
    host_candidates: &[PathBuf],
) {
    // 1. Dashboard bundle, if present: swap the whole `web/dist` directory so a

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Run `zeroclaw --version` manually to see whether the installed binary is actually broken or the failure was transient.
  2. Re-run `zeroclaw update`; a clean retry rewrites the binary and re-runs the smoke test.
  3. On Windows, check antivirus quarantine/history and add an exclusion for the zeroclaw install directory.
  4. If the binary is left broken, reinstall the previous or current release manually from the release page.
Defensive patterns

Strategy: fallback

Validate before calling

# after a failed automated update, verify the install before proceeding
zeroclaw --version || {
  echo 'update smoke test failed; binary broken' >&2
  # reinstall last-known-good from the release page
  exit 1
}

Try / catch

match run_update().await {
    Err(e) if e.to_string().contains("smoke test") => {
        // updater attempts rollback; verify with `zeroclaw --version`, then
        // either re-run the update or reinstall the previous release manually
    }
    other => other,
}

Prevention

When it happens

Trigger: `zeroclaw update` where the new binary validates in staging but fails once installed: missing execute permission after the swap, antivirus quarantining the new file (common on Windows), a partially written file, or runtime differences specific to the install path.

Common situations: Windows Defender/AV locking or quarantining freshly replaced executables; permission bits lost during the swap; disk errors during final write; the smoke-test child process killed by policy software.

Related errors


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