gitbutlerapp/gitbutler · error

Run `CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but`

Error message

Run `CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but` to build the `but` binary

What it means

Before creating or repairing the /usr/local/bin/but symlink, the installer verifies the built CLI binary exists at the expected Tauri target-dir path. If the `but` crate was never compiled into $PWD/target/tauri, it bails with the exact build command to run (crates/but-action/src/cli.rs:116).

Source

Thrown at crates/but-action/src/cli.rs:116

        }
    } else {
        Err(anyhow!(
            "Would probably need to run \"ln -sf '{}' '{UNIX_LINK_PATH}'\"{privilege}",
            cli_path.display(),
            privilege = if can_elevate_privileges {
                " with root permissions"
            } else {
                ""
            }
        ))
    }
}

fn ensure_cli_path_exists_prior_to_link(cli_path: &std::path::Path) -> anyhow::Result<()> {
    if cli_path.exists() {
        return Ok(());
    }
    bail!("Run `CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but` to build the `but` binary")
}

/// On Windows, we'll provide helpful instructions rather than attempt automatic installation
/// since:
/// 1. Creating symlinks requires developer mode or admin privileges
/// 2. There's no standard user-writable directory that's always in PATH
/// 3. Users typically add directories to PATH manually on Windows
///
/// Note that this isn't usually called on Windows.
#[cfg(windows)]
fn install_cli_windows(cli_path: std::path::PathBuf) -> anyhow::Result<()> {
    let but_filename = cli_path
        .file_name()
        .context("BUG: encountered but CLI path without /")?;

    bail!(
        "Automatic CLI installation is not supported on Windows.\n\
        \n\

View on GitHub (pinned to caf1f223d3)

Solutions

  1. From the repository root run `CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but`, then retry the install
  2. Verify the binary exists at the path reported by get_cli_path() before retrying
  3. If the target dir was moved, rebuild so the binary lands at the expected location

Example fix

# before: install CLI from the app -> bail: 'Run `CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but`...'
# after:
$ cd <repo-root>
$ CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but
$ # retry the install action; symlink is now created
Defensive patterns

Strategy: validation

Validate before calling

// Verify the built binary exists before install
let cli_path = get_cli_path()?;
if !cli_path.exists() {
    // run: CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but
    anyhow::bail!("build the but binary first: CARGO_TARGET_DIR=$PWD/target/tauri cargo build -p but");
}
do_install_cli(mode)?;

Prevention

When it happens

Trigger: Invoking the desktop app's 'install CLI' action (do_install_cli / ensure_cli_path_exists_prior_to_link) on a dev checkout where `cargo build -p but` was never run with CARGO_TARGET_DIR=$PWD/target/tauri, or where the target dir was cleaned/moved.

Common situations: Fresh clone after a clean/build step that skips the Rust CLI; running the app from a build that did not bundle the CLI; CI artifacts assembled without the but binary; cargo clean before installing.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/2415604f89158008. Report an issue: GitHub.