zellij-org/zellij · error

couldn't find 'cargo-zigbuild'

Error message

couldn't find 'cargo-zigbuild'

What it means

On macOS, the E2E release build cross-compiles zellij to a static musl binary (target matching the host arch) via cargo-zigbuild. Before invoking rustup/cargo, the task checks `which cargo-zigbuild` and aborts with this error (plus install hints printed to stderr) when it is not on PATH.

Source

Thrown at xtask/src/ci.rs:120

                cmd!(sh, "{cargo} build --release")
                    .run()
                    .map_err(anyhow::Error::new)
            })
            .context(err_context)
    } else if cfg!(target_os = "macos") {
        let target = if cfg!(target_arch = "aarch64") {
            "aarch64-unknown-linux-musl"
        } else {
            "x86_64-unknown-linux-musl"
        };
        crate::cargo()
            .and_then(|cargo| {
                if which::which("cargo-zigbuild").is_err() {
                    eprintln!("!! 'cargo-zigbuild' wasn't found but is needed on macOS.");
                    eprintln!("!! Please install it with:");
                    eprintln!("!!   cargo install cargo-zigbuild");
                    eprintln!("!!   brew install zig");
                    return Err(anyhow::anyhow!("couldn't find 'cargo-zigbuild'"));
                }
                cmd!(sh, "rustup target add {target}")
                    .run()
                    .map_err(anyhow::Error::new)?;
                cmd!(sh, "{cargo} zigbuild --release --target {target}")
                    .run()
                    .map_err(anyhow::Error::new)
            })
            .context(err_context)
    } else {
        crate::cargo()
            .and_then(|cargo| {
                cmd!(
                    sh,
                    "{cargo} build --release --target x86_64-unknown-linux-musl"
                )
                .run()
                .map_err(anyhow::Error::new)

View on GitHub (pinned to 98a0837077)

Solutions

  1. cargo install cargo-zigbuild
  2. brew install zig (zig provides the linker backend cargo-zigbuild needs)
  3. Verify with `which cargo-zigbuild`; if it fails, add ~/.cargo/bin to PATH and retry

Example fix

# before
cargo xtask ci e2e --build   # !! 'cargo-zigbuild' wasn't found

# after
cargo install cargo-zigbuild
brew install zig
cargo xtask ci e2e --build
Defensive patterns

Strategy: validation

Validate before calling

# on macOS, gate the e2e build on the toolchain being present
if [[ "$(uname)" == "Darwin" ]] && ! command -v cargo-zigbuild >/dev/null; then
  echo 'installing prerequisites: cargo-zigbuild + zig'
  cargo install cargo-zigbuild && brew install zig
fi
command -v cargo-zigbuild >/dev/null || { echo 'cargo-zigbuild required on macOS'; exit 1; }
cargo xtask ci e2e --build

Type guard

fn macos_e2e_toolchain_ready() -> bool {
    cfg!(target_os = "macos") && which::which("cargo-zigbuild").is_ok()
}

Try / catch

let out = Command::new("cargo").args(["xtask", "ci", "e2e", "--build"]).output()?;
let msg = String::from_utf8_lossy(&out.stderr);
if msg.contains("couldn't find 'cargo-zigbuild'") {
    run!("cargo install cargo-zigbuild")?;
    run!("brew install zig")?;
    rerun(out)?; // one retry after installing
} else if !out.status.success() {
    anyhow::bail!("e2e build failed: {}", msg);
}

Prevention

When it happens

Trigger: Running `cargo xtask ci e2e --build` on macOS when cargo-zigbuild is not installed, or when ~/.cargo/bin is missing from PATH so the installed binary is not found.

Common situations: Fresh macOS CI runners; local builds after a toolchain switch; PATH stripped in restricted shells or systemd-like environments.

Related errors


AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16). Data as JSON: /api/errors/8f008714ce24c5ac. Report an issue: GitHub.