{"record":{"id":"103812cd4f507cdb","repo":"gitbutlerapp/gitbutler","slug":"unknown-terminal-terminal-id","errorCode":null,"errorMessage":"Unknown terminal: {terminal_id}","messagePattern":"Unknown terminal: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-api/src/open/mod.rs","lineNumber":472,"sourceCode":"                    .arg(\"--args\")\n                    .arg(\"--working-directory\")\n                    .arg(&path);\n                run_terminal_command(cmd, \"Alacritty\", &path)?;\n            }\n            \"kitty\" => open_with_path(\"kitty\", Some(\"Kitty\"))?,\n            // WezTerm does not support `open -a WezTerm <path>`. Their docs state you have to use their CLI.\n            // https://wezterm.org/config/launch.html#specifying-the-current-working-directory\n            \"wezterm-mac\" => {\n                let cli_found = which::which(\"wezterm\").is_ok();\n                if !cli_found {\n                    return Err(anyhow::anyhow!(\"'wezterm' CLI was not found on PATH.\")\n                        .context(but_error::Code::DefaultTerminalNotFound));\n                }\n                let mut cmd = Command::new(\"wezterm\");\n                cmd.arg(\"start\").arg(\"--cwd\").arg(&path);\n                run_terminal_command(cmd, \"WezTerm\", &path)?;\n            }\n            _ => bail!(\"Unknown terminal: {terminal_id}\"),\n        };\n    } else if cfg!(target_os = \"linux\") {\n        let binary = terminal::terminal_binary(&terminal_id);\n\n        // Check if the terminal binary exists in PATH before attempting to launch.\n        // This lets us give a clear error directing users to Settings, rather than\n        // a vague launch failure (which could be confused with path issues).\n        let binary_found = which::which(binary).is_ok();\n        if !binary_found {\n            return Err(anyhow::anyhow!(\n                \"'{binary}' was not found. Make sure it is installed and available on your PATH.\"\n            )\n            .context(but_error::Code::DefaultTerminalNotFound));\n        }\n\n        match terminal_id.as_str() {\n            // Terminals that inherit parent process CWD (no explicit flags needed).\n            // Note: `binary` is used instead of the terminal ID because some terminals","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-api/src/open/mod.rs#L454-L490","documentation":"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'.","triggerScenarios":"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').","commonSituations":"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.","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"],"exampleFix":"// before\nawait client.openInTerminal('alacritty', repoPath); // macOS: Unknown terminal\n\n// after\nawait client.openInTerminal('alacritty-mac', repoPath);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"const MACOS_TERMINALS = new Set([\n  'terminal', 'iterm2', 'warp', 'ghostty', 'hyper',\n  'alacritty-mac', 'wezterm-mac', 'kitty',\n]);\n\nfunction isMacTerminalId(id: string): boolean {\n  return MACOS_TERMINALS.has(id);\n}","tryCatchPattern":"try {\n  await client.openInTerminal(terminalId, repoPath);\n} catch (e) {\n  if (String(e).startsWith('Unknown terminal')) {\n    const options = await client.getTerminalOptionsForPlatform('macos');\n    // re-ask the user to pick from options\n  } else throw e;\n}","preventionTips":["Populate terminal choices from getTerminalOptionsForPlatform, never hardcode","Store terminal preferences per-OS, not one global id","Remember macOS suffixed ids: alacritty-mac, wezterm-mac"],"tags":["terminal","macos","validation","settings","rust"],"backgroundTag":"unknown-terminal-id","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}