{"record":{"id":"0ec9b0652e15b526","repo":"espanso/espanso","slug":"unable-to-obtain-executable-path","errorCode":null,"errorMessage":"unable to obtain executable path","messagePattern":"unable to obtain executable path","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"espanso/src/path/mod.rs","lineNumber":153,"sourceCode":"        // Legacy macOS location in ~/Library/Preferences/espanso\n        debug!(\n            \"detected legacy config directory location at {}\",\n            legacy_mac_dir.display()\n        );\n        Some(legacy_mac_dir)\n    } else if let Some(config_dir) = get_default_config_dir() {\n        debug!(\n            \"detected default config directory at {}\",\n            config_dir.display()\n        );\n        Some(config_dir)\n    } else {\n        None\n    }\n}\n\nfn get_portable_config_dir() -> Option<PathBuf> {\n    let espanso_exe_path = std::env::current_exe().expect(\"unable to obtain executable path\");\n    let exe_dir = espanso_exe_path.parent();\n    if let Some(parent) = exe_dir {\n        let config_dir = parent.join(\".espanso\");\n        if config_dir.is_dir() {\n            return Some(config_dir);\n        }\n    }\n    None\n}\n\nfn get_home_espanso_dir() -> Option<PathBuf> {\n    if let Some(home_dir) = dirs::home_dir() {\n        let config_espanso_dir = home_dir.join(\".espanso\");\n        if config_espanso_dir.is_dir() {\n            return Some(config_espanso_dir);\n        }\n    }\n    None","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/espanso/espanso/blob/e6c3736675048026a057f1c4803d59242482fa7b/espanso/src/path/mod.rs#L135-L171","documentation":"get_portable_config_dir panics with 'unable to obtain executable path' when std::env::current_exe() returns Err. This function checks whether a '.espanso' folder exists next to the running executable to enable portable mode. current_exe fails when the OS cannot report the executable's path (e.g. the binary was deleted or replaced while running, or the platform facility like /proc/self/exe is unavailable).","triggerScenarios":"Calling get_config_dir/resolve_paths when the espanso binary has been deleted or renamed after launch (in-place upgrade), when executing via an environment where current_exe is unsupported, or in containers/jails lacking /proc. The binary itself being a bare name with no parent directory can also contribute to downstream failures.","commonSituations":"Package managers or update scripts replacing the espanso binary while it runs, self-update tooling deleting the executable before spawning the new one, running in minimal Docker images without /proc mounted, exotic interpreters/wrappers that break exe path resolution.","solutions":["Restart espanso from the installed binary after any update so current_exe resolves again.","Mount /proc (Linux) or provide the platform facility current_exe needs if running in a minimal container.","Use the --config-dir flag to bypass the portable config detection entirely.","Ensure the on-disk binary is not deleted/renamed while a process is still using it (update atomically, then restart)."],"exampleFix":"// before\n# updater deletes binary then notifies running instance\nrm /usr/bin/espanso && killall espanso  # old process panics on config lookup\n// after\nmv /usr/bin/espanso /usr/bin/espanso.new && install -m755 espanso /usr/bin/espanso && killall espanso  # old exe still resolvable until restart","handlingStrategy":"try-catch","validationCode":"if let Err(e) = std::env::current_exe() {\n    eprintln!(\"cannot resolve executable path: {e}; use --config-dir\");\n}","typeGuard":"fn exe_path_resolvable() -> bool {\n    std::env::current_exe().map(|p| p.is_file()).unwrap_or(false)\n}","tryCatchPattern":"let exe_path = std::env::current_exe().unwrap_or_else(|e| {\n    eprintln!(\"current_exe failed: {e}\");\n    std::process::exit(1);\n});","preventionTips":["Update the binary atomically and restart the process afterwards","Keep the installed executable on disk for the lifetime of the running process","Mount /proc in Linux containers","Use --config-dir to skip portable detection when exe resolution is unreliable"],"tags":["filesystem","current-exe","panic","portable-mode"],"backgroundTag":"file-not-found","analyzedSha":"e6c3736675048026a057f1c4803d59242482fa7b","analyzedAt":"2026-09-06T15:16:34.240Z","contentChangedAt":"2026-09-06T15:16:34.240Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}