gitbutlerapp/gitbutler · error · anyhow::Error
Path does not exist: {path}
Error message
Path does not exist: {path} What it means
Windows arm of open_in_terminal validates the directory before canonicalizing and launching (crates/but-api/src/open/mod.rs:533-537): if the given path does not exist on disk, it bails immediately. Only Windows performs this check; the path must exist before a terminal can be opened at it.
Source
Thrown at crates/but-api/src/open/mod.rs:536
};
} else if cfg!(windows) {
#[cfg(windows)]
fn create_new_console(cmd: &mut Command) -> &mut Command {
use std::os::windows::process::CommandExt;
// CREATE_NEW_CONSOLE: Creates a new console for the process (0x00000010)
// This allows the terminal to run independently without blocking our thread
const CREATE_NEW_CONSOLE: u32 = 0x00000010;
cmd.creation_flags(CREATE_NEW_CONSOLE)
}
#[cfg(not(windows))]
fn create_new_console(cmd: &mut Command) -> &mut Command {
cmd
}
// Validate path exists and canonicalize it to proper Windows format
let path_buf = Path::new(&path);
if !path_buf.exists() {
bail!("Path does not exist: {path}");
}
if !path_buf.is_dir() {
bail!("Path is not a directory: {path}");
}
// Canonicalize to get the absolute, properly formatted Windows path
// This converts forward slashes to backslashes and resolves . and ..
let canonical_path = gix::path::realpath(path_buf)
.with_context(|| format!("Failed to canonicalize path: {path}"))?
.to_str()
.context("BUG: input path is String, should be able to convert back to it")?
.to_owned();
let canonical_path = &canonical_path;
// Check if the terminal binary exists in PATH before attempting to launch.
let binary_found = which::which(&terminal_id).is_ok();
if !binary_found {
return Err(anyhow::anyhow!("'{terminal_id}' was not found.")View on GitHub (pinned to caf1f223d3)
Solutions
- Verify the path exists in Explorer and fix typos/changes, then retry openInTerminal
- If the project moved, update or re-add the project so GitButler stores the new location
- Reconnect the drive/mount before opening terminals in projects on removable media
Defensive patterns
Strategy: validation
Validate before calling
import { stat } from 'fs/promises';
try {
await stat(repoPath);
} catch {
throw new Error(`Project path missing on disk: ${repoPath}`);
}
await client.openInTerminal(terminalId, repoPath); Try / catch
try {
await client.openInTerminal(terminalId, repoPath);
} catch (e) {
if (String(e).startsWith('Path does not exist')) {
// prompt to re-locate or re-add the project
} else throw e;
} Prevention
- Check the project directory still exists before showing 'open in terminal'
- Update the stored project path when the repo is moved or renamed
- Handle removable-media/network-drive projects gracefully
When it happens
Trigger: Opening a terminal at a project directory that was moved, renamed, or deleted on disk; a stale project record pointing at an unmounted network drive or removed removable media.
Common situations: Repo moved outside GitButler; drive letter changed; project added from a USB/network mount that is gone; path with stale casing after a rename.
Related errors
- Path is not a directory: {path}
- The path {} does not exist
- The path {} is not a directory
- When using OpenAI in a bring your own key configuration, you
- BUG: we do not create or work with symlinks
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/ccffc1d46f2df52a.
Report an issue: GitHub.