libnyanpasu/clash-nyanpasu · error · std::io::Error (NotFound)
Couldn't get file name of curent executable.
Error message
Couldn't get file name of curent executable.
What it means
The Linux deep-link register() names the generated .desktop file after the current executable (`<name>-handler.desktop`). It calls current_exe().file_name(); when the executable path has no final component (root of a filesystem, deleted path, or exotic exec setup), it fails with this NotFound io::Error.
Source
Thrown at backend/tauri-plugin-deep-link/src/linux.rs:26
use dirs::data_dir;
use crate::ID;
pub fn register<F: FnMut(String) + Send + 'static>(schemes: &[&str], handler: F) -> Result<()> {
listen(handler)?;
let mut target = data_dir()
.ok_or_else(|| Error::new(ErrorKind::NotFound, "data directory not found."))?
.join("applications");
create_dir_all(&target)?;
let exe = tauri_utils::platform::current_exe()?;
let file_name = format!(
"{}-handler.desktop",
exe.file_name()
.ok_or_else(|| Error::new(
ErrorKind::NotFound,
"Couldn't get file name of curent executable.",
))?
.to_string_lossy()
);
target.push(&file_name);
let mime_types = format!(
"{};",
schemes
.iter()
.map(|s| format!("x-scheme-handler/{}", s))
.collect::<Vec<String>>()
.join(";")
);
let mut file = File::create(&target)?;View on GitHub (pinned to f7dbce2997)
Solutions
- Ensure the app is launched from a normal on-disk executable path with a file name
- Check the inner path: log tauri_utils::platform::current_exe() to see what path was resolved
- Avoid running the binary from paths like "/" or from unlinked temp files
- If the exotic launch mode is intentional, generate a stable .desktop name from a constant (e.g. the app identifier) instead of exe.file_name()
Example fix
// before
exe.file_name().ok_or_else(|| Error::new(ErrorKind::NotFound, "Couldn't get file name of curent executable."))?
// after
let name = exe.file_name().map(|n| n.to_string_lossy().into_owned())
.unwrap_or_else(|| "nyanpasu".to_string());
let file_name = format!("{name}-handler.desktop"); Defensive patterns
Strategy: validation
Validate before calling
// before register()
let exe = tauri_utils::platform::current_exe()?;
if exe.file_name().is_none() {
anyhow::bail!("current exe path {:?} has no file name; cannot build .desktop name", exe);
} Type guard
fn exe_has_file_name(path: &std::path::Path) -> bool {
path.file_name().is_some()
} Try / catch
match deep_link::register(&schemes, handler) {
Err(e) if e.to_string().contains("file name of curent executable") => {
log::error!("exe path unusable for .desktop naming: {e}");
}
Err(e) => return Err(e.into()),
Ok(()) => {}
} Prevention
- Launch the app from a normal on-disk path, never "/" or unlinked temp files
- Log current_exe() at startup to detect odd resolution environments early
- Prefer a constant .desktop name derived from the app identifier over exe-derived names in exotic setups
When it happens
Trigger: register() invoked when std::env::current_exe() / tauri's current_exe returns a path whose file_name() is None — e.g. the binary path is "/", the path was unlinked after exec, or running via unusual mount setups.
Common situations: Container or chroot layouts where /proc/self/exe resolves oddly; app executed from a deleted temp directory; memory-fd execution; symlinks pointing to filesystem root after misconfiguration.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Couldn't get file name of current executable.
- data directory not found.
- Called register() before prepare()
- listen() called before prepare()
- Can't create listener
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/fbd26480dd8576c2.
Report an issue: GitHub.