gitbutlerapp/gitbutler · error
osascript directory picker failed (exit {:?}): {}
Error message
osascript directory picker failed (exit {:?}): {} What it means
The macOS directory picker in but-server shells out to osascript running 'choose folder'. A non-zero exit whose stderr is not one of the user-cancel markers ('User canceled' or error -128) is treated as a real failure and bailed with the exit code and stderr; an actual user cancel returns Ok(None).
Source
Thrown at crates/but-server/src/lib.rs:129
/// Shell out to a platform-native directory picker.
fn native_pick_directory() -> anyhow::Result<Option<String>> {
#[cfg(target_os = "macos")]
{
let output = std::process::Command::new("osascript")
.arg("-e")
.arg(
r#"set theFolder to choose folder with prompt "Select a Git repository"
return POSIX path of theFolder"#,
)
.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
// osascript exits with code 1 and "User canceled" on cancel
if stderr.contains("User canceled") || stderr.contains("(-128)") {
return Ok(None);
}
anyhow::bail!(
"osascript directory picker failed (exit {:?}): {}",
output.status.code(),
if stderr.is_empty() {
"unknown error"
} else {
&stderr
}
);
}
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
if path.is_empty() {
return Ok(None);
}
// osascript returns paths with a trailing slash — strip it
Ok(Some(path.trim_end_matches('/').to_string()))
}
#[cfg(target_os = "linux")]View on GitHub (pinned to caf1f223d3)
Solutions
- Grant the hosting app/terminal Automation permission for Finder/System Events (System Settings > Privacy & Security > Automation)
- Run the picker from a normal GUI session, not SSH or a daemon context
- Inspect the exit code and stderr embedded in the message to identify the AppleScript failure
Defensive patterns
Strategy: fallback
Validate before calling
// Rust: probe osascript availability before offering the native picker
let available = which::which("osascript").is_ok();
offer_picker = available && is_gui_session(); // DISPLAY/WindowServer present Try / catch
Cancel already maps to Ok(None); for real failures, catch the bail, show the exit code/stderr, hint at System Settings > Privacy & Security > Automation, and fall back to a manual path input field.
Prevention
- Request Automation permission early in app setup on macOS
- Do not invoke the picker from SSH or daemon contexts; detect GUI sessions first
When it happens
Trigger: Running the pick-directory flow on macOS where osascript fails for reasons other than cancel: Automation/Finder permission denied to the hosting process, osascript missing or broken, or no WindowServer connection (SSH/headless).
Common situations: The app or terminal lacks Automation permission under macOS privacy settings; running the binary over SSH; corporate hardening that removes or restricts osascript.
Related errors
- Failed to move new installation into place: {e}
- Failed to create symlink: {e}. No backup available to restor
- directory picker failed (exit {code}): {}
- CliInstallCancelled
- osascript exited with status {}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/24183f3e85248471.
Report an issue: GitHub.