gitbutlerapp/gitbutler · error · anyhow::Error
Could not find '{}'. Please make sure it is in your `PATH` o
Error message
Could not find '{}'. Please make sure it is in your `PATH` or configure the full path using `gpg.program` in the Git configuration What it means
The GPG signing path spawns the program from gpg.program (default 'gpg') and maps std::io::ErrorKind::NotFound from spawn to this friendly message: the executable could not be located at all. Other spawn failures get a different, generic context, so this error is specifically 'binary not on PATH / configured path wrong'.
Source
Thrown at crates/but-core/src/commit/mod.rs:418
let gpg_program = match config.trusted_path("gpg.program")? {
Some(program) if !program.as_os_str().is_empty() => program,
_ => Path::new("gpg").into(),
};
let mut cmd = into_command(
prepare_with_shell_on_windows(&gpg_program)
.args(["--status-fd=2", "-bsau"])
.arg(gix::path::from_bstring(signing_key))
.arg("-"),
);
cmd.stdout(Stdio::piped())
.stderr(Stdio::piped())
.stdin(Stdio::piped());
let mut child = match cmd.spawn() {
Ok(child) => child,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
bail!(
"Could not find '{}'. Please make sure it is in your `PATH` or configure the full path using `gpg.program` in the Git configuration",
gpg_program.display()
)
}
Err(err) => {
return Err(err).context(format!("Could not execute GPG program using {cmd:?}"));
}
};
child.stdin.take().expect("configured").write_all(buffer)?;
let output = child.wait_with_output()?;
if output.status.success() {
Ok(BString::new(output.stdout))
} else {
let stderr = BString::new(output.stderr);
let stdout = BString::new(output.stdout);
bail!("Failed to sign GPG: {stdout} {stderr}");
}View on GitHub (pinned to caf1f223d3)
Solutions
- Install GPG (gnupg / Gpg4win / gpgsuite) and restart the app so the new PATH is picked up
- Set the absolute path in git config: git config --global gpg.program /opt/homebrew/bin/gpg (or /usr/bin/gpg, C:\Program Files\GnuPG\bin\gpg.exe)
- Verify from the same environment the app runs in: 'command -v gpg' inside that shell
- If signing is not actually wanted, unset it: git config --unset gpg.program / user.signingkey / commit.gpgsign
Example fix
# before: 'gpg' not on the app's PATH git config --global gpg.program gpg # after: pin the absolute path git config --global gpg.program "$(command -v gpg)" git commit -S -m 'signed'
Defensive patterns
Strategy: validation
Validate before calling
// resolve the configured program before committing
let program = git_config.trusted_path("gpg.program")?.unwrap_or_else(|| "gpg".into());
anyhow::ensure!(
which::which(&program).is_ok(),
"gpg program '{}' not found — install GnuPG or set gpg.program to its absolute path",
program.display()
); Try / catch
match sign_buffer(&repo, &buffer).await {
Err(e) if e.to_string().contains("make sure it is in your `PATH`") =>
Err(e.context("install GnuPG or: git config --global gpg.program /full/path/to/gpg")),
r => r?,
} Prevention
- Set gpg.program to an absolute path on machines where GUI-launched apps have a minimal PATH
- Install gnupg/Gpg4win as part of the workstation setup for signed-commit workflows
- Probe for the signer at app startup and warn before the user types a commit message
When it happens
Trigger: Committing with signing enabled on a machine where gpg is not installed, where the app's environment lacks the directory containing gpg (GUI apps on macOS/Windows get a minimal PATH), or where gpg.program is set to a nonexistent or moved binary.
Common situations: Desktop app launched from Finder/Start Menu whose PATH omits /usr/local/bin or /opt/homebrew/bin; gpgsuite/Gpg4win uninstalled but git config still points at the old path; minimal containers/CI images without gnupg.
Related errors
- Failed to sign SSH: {stdout} {stderr}
- Failed to sign GPG: {stdout} {stderr}
- The repository at {} has no working directory. GitButler req
- Failed to communicate with LM Studio server: ${error instanc
- Invalid response: ${JSON.stringify(result)}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/40e11874f9a1a2af.
Report an issue: GitHub.