gitbutlerapp/gitbutler · error
Shell configuration cannot be performed without a connected…
Error message
Shell configuration cannot be performed without a connected terminal
What it means
configure_shell edits shell rc files interactively and is documented to require a connected terminal; it bails when ui::is_connected_to_terminal() is false. This prevents silently rewriting dotfiles or hanging on prompts in headless environments.
Solutions
- Run the installer in an interactive terminal so PATH edits can be confirmed
- Skip shell configuration (configure manually by adding the bin dir to PATH yourself)
- Use `ssh -t` or a PTY wrapper when installing over SSH
- Pre-set PATH via environment/config in automation so interactive shell setup is unnecessary
Example fix
// before ssh deploy@host "but install" // after ssh -t deploy@host "but install" # allocate a TTY # or manually: echo 'export PATH="$HOME/.bin:$PATH"' >> ~/.bashrc
Defensive patterns
Strategy: fallback
Validate before calling
if !std::io::stdin().is_terminal() {
// skip shell configuration; print manual PATH instructions instead
} Try / catch
match result {
Err(e) if e.to_string().contains("connected terminal") => {
// print manual shell-config instructions and continue non-interactively
}
other => other?,
} Prevention
- Run installers in a real terminal or PTY (ssh -t, script)
- Skip interactive shell setup in CI and configure PATH manually
- Check terminal availability before starting interactive install
When it happens
Trigger: run_installation_impl reaching the shell-configuration step without a TTY — installer run in CI, Docker, cron, piped output, or after interactive mode was skipped.
Common situations: Installing via automation scripts, containers without a PTY, remote SSH without a TTY allocation (`ssh host but install` instead of `ssh -t`), output piped to a log file.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- interactive mode requested, but there is no terminal to…
- Human input required - run this in a terminal, or specify…
- Interactive setup requires a terminal. Use `but agent setup…
- Local AI configuration requires running inside a git…
- No target branch is configured and none could be inferred…
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/092148342e8e1b86.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-installer/src/shell.rs:180
|| (trimmed.contains("set") && trimmed.contains("PATH"))
});
let has_completions = contents.contains("but completions");
Some(ShellConfig {
shell: ShellType::Fish,
config_path,
has_completions,
has_path,
})
}
}
/// Interactively add shell configurations for the user.
///
/// This is designed to run interactively and errors if [`ui::is_connected_to_terminal`] returns `false`.
pub(crate) fn configure_shell(home_dir: &Path) -> Result<()> {
if !ui::is_connected_to_terminal() {
anyhow::bail!("Shell configuration cannot be performed without a connected terminal");
}
let detected_shell_configs: Vec<ShellConfig> =
[ShellType::Bash, ShellType::Zsh, ShellType::Fish]
.map(|config| config.detect_config(home_dir))
.into_iter()
.flatten()
.collect();
let num_detected_shells = detected_shell_configs.len();
let unconfigured_shells: Vec<ShellConfig> = detected_shell_configs
.into_iter()
.filter(|cfg| !cfg.is_fully_configured())
.collect();
for cfg in &unconfigured_shells {
ui::println_empty();
info(&format!(View on GitHub (pinned to 58e5313667)