{"record":{"id":"ccffc1d46f2df52a","repo":"gitbutlerapp/gitbutler","slug":"path-does-not-exist-path","errorCode":null,"errorMessage":"Path does not exist: {path}","messagePattern":"Path does not exist: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-api/src/open/mod.rs","lineNumber":536,"sourceCode":"        };\n    } else if cfg!(windows) {\n        #[cfg(windows)]\n        fn create_new_console(cmd: &mut Command) -> &mut Command {\n            use std::os::windows::process::CommandExt;\n            // CREATE_NEW_CONSOLE: Creates a new console for the process (0x00000010)\n            // This allows the terminal to run independently without blocking our thread\n            const CREATE_NEW_CONSOLE: u32 = 0x00000010;\n            cmd.creation_flags(CREATE_NEW_CONSOLE)\n        }\n        #[cfg(not(windows))]\n        fn create_new_console(cmd: &mut Command) -> &mut Command {\n            cmd\n        }\n\n        // Validate path exists and canonicalize it to proper Windows format\n        let path_buf = Path::new(&path);\n        if !path_buf.exists() {\n            bail!(\"Path does not exist: {path}\");\n        }\n        if !path_buf.is_dir() {\n            bail!(\"Path is not a directory: {path}\");\n        }\n\n        // Canonicalize to get the absolute, properly formatted Windows path\n        // This converts forward slashes to backslashes and resolves . and ..\n        let canonical_path = gix::path::realpath(path_buf)\n            .with_context(|| format!(\"Failed to canonicalize path: {path}\"))?\n            .to_str()\n            .context(\"BUG: input path is String, should be able to convert back to it\")?\n            .to_owned();\n        let canonical_path = &canonical_path;\n\n        // Check if the terminal binary exists in PATH before attempting to launch.\n        let binary_found = which::which(&terminal_id).is_ok();\n        if !binary_found {\n            return Err(anyhow::anyhow!(\"'{terminal_id}' was not found.\")","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-api/src/open/mod.rs#L518-L554","documentation":"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.","triggerScenarios":"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.","commonSituations":"Repo moved outside GitButler; drive letter changed; project added from a USB/network mount that is gone; path with stale casing after a rename.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { stat } from 'fs/promises';\n\ntry {\n  await stat(repoPath);\n} catch {\n  throw new Error(`Project path missing on disk: ${repoPath}`);\n}\nawait client.openInTerminal(terminalId, repoPath);","typeGuard":null,"tryCatchPattern":"try {\n  await client.openInTerminal(terminalId, repoPath);\n} catch (e) {\n  if (String(e).startsWith('Path does not exist')) {\n    // prompt to re-locate or re-add the project\n  } else throw e;\n}","preventionTips":["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"],"tags":["terminal","windows","filesystem","path","rust"],"backgroundTag":"path-not-found","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}