{"record":{"id":"4b08c5236834b427","repo":"gitbutlerapp/gitbutler","slug":"cannot-attempt-to-open-non-existing-directory","errorCode":null,"errorMessage":"Cannot attempt to open non-existing directory: '{}'","messagePattern":"Cannot attempt to open non-existing directory: '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/gitbutler-tauri/src/debug.rs","lineNumber":33,"sourceCode":"#[instrument(err(Debug))]\npub fn open_config_folder() -> Result<(), Error> {\n    open_existing(but_path::app_config_dir()?)\n}\n\n/// Opens the cache folder in the system file manager\n#[instrument(err(Debug))]\npub fn open_cache_folder() -> Result<(), Error> {\n    open_existing(but_path::app_cache_dir()?)\n}\n\n/// Open `dir` but refuse to do so if that would definitely fail as it's not a directory,\n/// or it doesn't exist.\n///\n/// We can assume the directories exist.\nfn open_existing(dir: impl AsRef<Path>) -> Result<(), Error> {\n    let dir = dir.as_ref();\n    if !dir.exists() {\n        return Err(anyhow!(\n            \"Cannot attempt to open non-existing directory: '{}'\",\n            dir.display()\n        )\n        .into());\n    }\n    if !dir.is_dir() {\n        return Err(anyhow!(\n            \"Cannot attempt to open anything but a directory: '{}'\",\n            dir.display()\n        )\n        .into());\n    }\n\n    let is_macos_stable_build =\n        cfg!(target_os = \"macos\") && matches!(AppChannel::new(), AppChannel::Release);\n    // On macOS stable builds, it would try to open `com.gitbutler.app` and treat it as application,\n    // which would fail. Instead, we reveal, which selects the directory in the finder and users\n    // can right-click it to see the package contents. Better than nothing.","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/gitbutler-tauri/src/debug.rs#L15-L51","documentation":"open_existing() in the Tauri debug module opens a folder in the OS file manager. It first asserts the directory exists; if not, it returns this anyhow error wrapped as Error. Although callers normally pass directories that already exist, this guards against a missing logs/config/cache folder.","triggerScenarios":"Calling open_logs_folder, open_config_folder, or open_cache_folder before the corresponding directory has been created (e.g. on first launch before any log/config write, or when cache was cleared externally).","commonSituations":"Fresh install where the user clicks 'Open logs' before anything was logged; cache directory deleted by a cleanup tool; portable/custom-dir installs where the dir was never initialized.","solutions":["Trigger the action that creates the folder first (produce a log, save settings) and retry.","Manually create the missing folder and retry the open.","Reinstall/relaunch the app so default folders are initialized."],"exampleFix":"// before (caller)\nopen_logs_folder()?;\n// after\nstd::fs::create_dir_all(&logs_dir)?;\nopen_logs_folder()?;","handlingStrategy":"validation","validationCode":"if (!fs.existsSync(logsDir)) fs.mkdirSync(logsDir, { recursive: true });\nopen_logs_folder();","typeGuard":"const dirExists = (p) => fs.existsSync(p) && fs.statSync(p).isDirectory();","tryCatchPattern":"try { open_logs_folder(); } catch (e) { if (String(e).includes('non-existing directory')) { fs.mkdirSync(logsDir, {recursive:true}); open_logs_folder(); } else { throw e; } }","preventionTips":["Ensure log/config/cache dirs are created at app startup.","Create the directory lazily before any 'open folder' action.","Warn users when external tools delete app directories."],"tags":["filesystem","tauri","directory"],"backgroundTag":"directory-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"}