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

  1. Run the installer in an interactive terminal so PATH edits can be confirmed
  2. Skip shell configuration (configure manually by adding the bin dir to PATH yourself)
  3. Use `ssh -t` or a PTY wrapper when installing over SSH
  4. 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

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


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)