gitbutlerapp/gitbutler · error · anyhow::Error

Unknown terminal: {terminal_id}

Error message

Unknown terminal: {terminal_id}

What it means

macOS arm of open_in_terminal matches terminal_id against a fixed allowlist (terminal, iterm2, warp, ghostty, hyper, alacritty-mac, wezterm-mac, kitty); any other id reaches the fallthrough bail at crates/but-api/src/open/mod.rs:472. Note macOS-specific ids: 'alacritty-mac' and 'wezterm-mac', not 'alacritty'/'wezterm'.

Source

Thrown at crates/but-api/src/open/mod.rs:472

                    .arg("--args")
                    .arg("--working-directory")
                    .arg(&path);
                run_terminal_command(cmd, "Alacritty", &path)?;
            }
            "kitty" => open_with_path("kitty", Some("Kitty"))?,
            // WezTerm does not support `open -a WezTerm <path>`. Their docs state you have to use their CLI.
            // https://wezterm.org/config/launch.html#specifying-the-current-working-directory
            "wezterm-mac" => {
                let cli_found = which::which("wezterm").is_ok();
                if !cli_found {
                    return Err(anyhow::anyhow!("'wezterm' CLI was not found on PATH.")
                        .context(but_error::Code::DefaultTerminalNotFound));
                }
                let mut cmd = Command::new("wezterm");
                cmd.arg("start").arg("--cwd").arg(&path);
                run_terminal_command(cmd, "WezTerm", &path)?;
            }
            _ => bail!("Unknown terminal: {terminal_id}"),
        };
    } else if cfg!(target_os = "linux") {
        let binary = terminal::terminal_binary(&terminal_id);

        // Check if the terminal binary exists in PATH before attempting to launch.
        // This lets us give a clear error directing users to Settings, rather than
        // a vague launch failure (which could be confused with path issues).
        let binary_found = which::which(binary).is_ok();
        if !binary_found {
            return Err(anyhow::anyhow!(
                "'{binary}' was not found. Make sure it is installed and available on your PATH."
            )
            .context(but_error::Code::DefaultTerminalNotFound));
        }

        match terminal_id.as_str() {
            // Terminals that inherit parent process CWD (no explicit flags needed).
            // Note: `binary` is used instead of the terminal ID because some terminals

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Use only ids returned by getTerminalOptionsForPlatform('macos')
  2. Re-select the terminal in Settings so a valid id is persisted
  3. On macOS remember the suffixed ids: alacritty-mac and wezterm-mac

Example fix

// before
await client.openInTerminal('alacritty', repoPath); // macOS: Unknown terminal

// after
await client.openInTerminal('alacritty-mac', repoPath);
Defensive patterns

Strategy: type-guard

Type guard

const MACOS_TERMINALS = new Set([
  'terminal', 'iterm2', 'warp', 'ghostty', 'hyper',
  'alacritty-mac', 'wezterm-mac', 'kitty',
]);

function isMacTerminalId(id: string): boolean {
  return MACOS_TERMINALS.has(id);
}

Try / catch

try {
  await client.openInTerminal(terminalId, repoPath);
} catch (e) {
  if (String(e).startsWith('Unknown terminal')) {
    const options = await client.getTerminalOptionsForPlatform('macos');
    // re-ask the user to pick from options
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a terminal id valid on another platform ('gnome-terminal', 'wt') on macOS, a typo, or a stale persisted settings value from before an id rename ('alacritty' vs 'alacritty-mac').

Common situations: Cross-platform code storing one terminal preference for all OSes; settings migrated between versions; hand-written integrations guessing ids instead of using the platform list.

Related errors


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