zed-industries/zed · error

zig not found on $PATH, install zig (see https://ziglang.org

Error message

zig not found on $PATH, install zig (see https://ziglang.org/learn/getting-started or use zigup)

What it means

When Zed must build the remote server from source for a cross-compilation target (no prebuilt available, or a from-source/dev build), it uses zig as the cross toolchain. Before proceeding it probes `which zig`; if zig is absent it bails with a platform-specific install hint (crates/remote/src/transport.rs:348). rustup is required immediately after for `rustup target add`.

Source

Thrown at crates/remote/src/transport.rs:348

            new_command("cargo")
                .current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
                .args([
                    "build",
                    "--package",
                    "remote_server",
                    "--features",
                    "debug-embed",
                    "--target-dir",
                    "target/remote_server",
                    "--target",
                    &triple,
                ])
                .env("RUSTFLAGS", &rust_flags),
        )
        .await?;
    } else {
        if which("zig", cx).await?.is_none() {
            anyhow::bail!(if cfg!(not(windows)) {
                "zig not found on $PATH, install zig (see https://ziglang.org/learn/getting-started or use zigup)"
            } else {
                "zig not found on $PATH, install zig (use `winget install -e --id zig.zig` or see https://ziglang.org/learn/getting-started or use zigup)"
            });
        }

        let rustup = which("rustup", cx)
            .await?
            .context("rustup not found on $PATH, install rustup (see https://rustup.rs/)")?;
        delegate.set_status(Some("Adding rustup target for cross-compilation"), cx);
        log::info!("adding rustup target");
        run_cmd(new_command(rustup).args(["target", "add"]).arg(&triple)).await?;

        if which("cargo-zigbuild", cx).await?.is_none() {
            delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx);
            log::info!("installing cargo-zigbuild");
            run_cmd(new_command("cargo").args(["install", "--locked", "cargo-zigbuild"])).await?;
        }

View on GitHub (pinned to f4178619ac)

Solutions

  1. Install zig - via zigup, `winget install -e --id zig.zig` on Windows, or your package manager - and make sure it is on PATH in the environment Zed launches from
  2. Verify with `which zig` and `zig version` in that same shell
  3. Also ensure rustup is installed, since the next step runs `rustup target add <triple>`
  4. Prefer prebuilt servers (stable Zed on common platforms) so no build is needed

Example fix

# before
$ which zig
(no output)

# after
$ brew install zig   # or: winget install -e --id zig.zig / curl -L https://zigup.rs | sh
$ zig version
0.13.0
Defensive patterns

Strategy: validation

Validate before calling

use which::which;

if which("zig").is_err() {
    eprintln!("zig is required to cross-compile the remote server from source");
    // install zig (and rustup) before attempting the connection
}
if which("rustup").is_err() {
    eprintln!("rustup is required next (rustup target add <triple>)");
}

Prevention

When it happens

Trigger: Connecting to a remote platform that has no prebuilt server (or forcing a from-source build) from a machine without zig on PATH - the cross-compile path runs and the `which("zig")` probe returns None.

Common situations: Dev builds / ZED_FROM_SOURCE workflows; remote-developing to unusual platforms; fresh dev machines that have rustup but no zig.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/7969e7f8ad9cd766. Report an issue: GitHub.