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

  1. Verify the path exists in Explorer and fix typos/changes, then retry openInTerminal
  2. If the project moved, update or re-add the project so GitButler stores the new location
  3. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/ccffc1d46f2df52a. Report an issue: GitHub.