gitbutlerapp/gitbutler · error
No supported agent was detected. In non-interactive mode, sp
Error message
No supported agent was detected. In non-interactive mode, specify --path or --detect. Use --path <path> to choose an installation directory, or --detect to update an existing installation.
What it means
When `but skill install` cannot infer an installation path (no --path, no --detect, and no driving agent detected to supply a default), it falls back to interactive prompting in prompt_for_install_path. Prompting is impossible when the output channel is not human-readable (out.for_human() is None: piped stdout or --output-format json), so the command aborts and lists the non-interactive options.
Source
Thrown at crates/but/src/command/skill/mod.rs:875
.prompt_select("Where would you like to install the skill?", &options)?
.copied()
{
Some(InstallScopeOption::Local) => Ok(InstallScope::Local),
Some(InstallScopeOption::Global) => Ok(InstallScope::Global),
None => Err(UserCancelled.into()),
}
}
/// Prompt user to select installation scope and format
fn prompt_for_install_path(
ctx: Option<&mut Context>,
global: bool,
out: &mut OutputChannel,
progress: &mut impl std::io::Write,
) -> Result<PathBuf> {
let t = theme::get();
if out.for_human().is_none() {
anyhow::bail!(
"No supported agent was detected. In non-interactive mode, specify --path or --detect. Use --path <path> to choose an installation directory, or --detect to update an existing installation."
);
}
if !out.can_prompt() {
anyhow::bail!(
"Human input required - run this in a terminal, or specify --path/--detect to avoid interactive prompts."
);
}
let local_scope_available = if !global {
match ctx.as_ref() {
Some(ctx) => {
let repo = ctx.repo.get()?;
repo.workdir().is_some()
}
None => false,
}
} else {View on GitHub (pinned to caf1f223d3)
Solutions
- Pass `--path <dir>` to choose the installation directory explicitly
- Pass `--detect` to update an existing installation non-interactively
- Run the command in a real terminal so interactive prompting works
Example fix
$ but skill install | tee install.log # fails: no human output $ but skill install --path ~/.claude/skills # non-interactive OK
Defensive patterns
Strategy: validation
Validate before calling
use std::io::IsTerminal;
// before invoking in scripts:
if !std::io::stdout().is_terminal() {
cmd.args(["--path", explicit_dir]); // never rely on prompts when piped
} Prevention
- Scripts should always pass --path or --detect
- Treat non-TTY environments as requiring explicit flags
- Smoke-test install steps with piped output in CI to catch this early
When it happens
Trigger: `but skill install` with stdout piped (e.g. `| tee log`), run with --output-format json, or executed in CI where for_human() returns None and detect_agent found no supported agent to derive a default path.
Common situations: CI/CD pipelines installing skills, agent harnesses driving the CLI without a TTY, Docker build steps, piping output to a file or pager.
Related errors
- Interactive setup requires a terminal. Use `but agent setup
- Could not detect an existing GitButler skill installation. R
- Human input required - run this in a terminal, or specify --
- Cannot use both --detect and --path options together
- Installation path {} is a file, not a directory. Please spec
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7941cbeb1d20e2fd.
Report an issue: GitHub.