{"record":{"id":"468ee21cfecfbfb9","repo":"gitbutlerapp/gitbutler","slug":"powershell-directory-picker-failed-exit","errorCode":null,"errorMessage":"PowerShell directory picker failed (exit {:?}): {}","messagePattern":"PowerShell directory picker failed \\(exit (.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-server/src/lib.rs","lineNumber":206,"sourceCode":"    }\n\n    #[cfg(target_os = \"windows\")]\n    {\n        // Use the modern IFileOpenDialog via PowerShell (STA is required for\n        // any Windows Forms/COM dialog). FolderBrowserDialog is directory-only.\n        // The script outputs the selected path on OK, or empty string on cancel.\n        // A non-zero exit means PowerShell itself failed (e.g. Add-Type error).\n        let output = std::process::Command::new(\"powershell\")\n            .args([\n                \"-NoProfile\",\n                \"-STA\",\n                \"-Command\",\n                r#\"Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.FolderBrowserDialog; $f.Description = 'Select a Git repository'; $f.UseDescriptionForTitle = $true; if ($f.ShowDialog() -eq 'OK') { $f.SelectedPath } else { '' }\"#,\n            ])\n            .output()?;\n        if !output.status.success() {\n            let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();\n            anyhow::bail!(\n                \"PowerShell directory picker failed (exit {:?}): {}\",\n                output.status.code(),\n                if stderr.is_empty() {\n                    \"unknown error\"\n                } else {\n                    &stderr\n                }\n            );\n        }\n        let path = String::from_utf8_lossy(&output.stdout).trim().to_string();\n        if path.is_empty() {\n            return Ok(None);\n        }\n        Ok(Some(path))\n    }\n\n    #[cfg(not(any(target_os = \"macos\", target_os = \"linux\", target_os = \"windows\")))]\n    {","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-server/src/lib.rs#L188-L224","documentation":"On Windows, `native_pick_directory` runs PowerShell with a `FolderBrowserDialog` (WinForms) to show a folder chooser; empty stdout means the user cancelled (returns Ok(None)). If the PowerShell process exits non-zero, the server raises this error with the exit code and stderr (or \"unknown error\").","triggerScenarios":"Invoking the native directory-pick endpoint on Windows when the PowerShell child process fails: PowerShell not on PATH, execution policy blocking the -Command, WinForms/assembly load failure, or a non-interactive session where the dialog cannot be shown.","commonSituations":"Running but-server as a service or over SSH with no interactive desktop (STA/dialog unavailable); restricted PowerShell execution policy or Constrained Language Mode; stripped-down Windows installs missing .NET WinForms components.","solutions":["Check the exit code/stderr in the message; for execution-policy issues, allow script/command execution for the invoking user.","Run the server in an interactive user session so the WinForms dialog can be displayed (not as a headless service).","Verify PowerShell launches (`pwsh`/`powershell -Command \"echo ok\"`) and that .NET Framework/WinForms is available.","Skip the native picker and pass the directory path explicitly through the API/CLI."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Windows: confirm PowerShell can execute commands before requesting the native picker\npowershell -NoProfile -Command \"echo ok\"","typeGuard":"fn windows_picker_ready(powershell_ok: bool, interactive_session: bool) -> bool {\n    powershell_ok && interactive_session\n}","tryCatchPattern":"match pick_directory().await {\n    Err(e) if e.to_string().contains(\"PowerShell directory picker failed\") => {\n        let dir = prompt_for_path_manually(); // fallback to text input\n    }\n    other => other?,\n}","preventionTips":["Run the server in an interactive desktop session so the WinForms dialog can open.","Ensure PowerShell execution policy permits -Command invocations for the service user.","Verify .NET/WinForms availability on minimal Windows images.","Provide a manual path-entry fallback for service/headless deployments."],"tags":["windows","powershell","native-dialog","process"],"backgroundTag":"command-not-found","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}