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 terminalsView on GitHub (pinned to caf1f223d3)
Solutions
- Use only ids returned by getTerminalOptionsForPlatform('macos')
- Re-select the terminal in Settings so a valid id is persisted
- 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
- Populate terminal choices from getTerminalOptionsForPlatform, never hardcode
- Store terminal preferences per-OS, not one global id
- Remember macOS suffixed ids: alacritty-mac, wezterm-mac
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
- {terminal_name} exited with non-zero status: {status_code}
- Failed to open {terminal_name} ({status_code}): {stderr}
- Path is not a directory: {path}
- Invalid message format
- HTTP Error ${response.statusText}: ${text}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/103812cd4f507cdb.
Report an issue: GitHub.