{"record":{"id":"0534eeb4fc3a6a55","repo":"libnyanpasu/clash-nyanpasu","slug":"couldn-t-get-file-name-of-current-executable","errorCode":null,"errorMessage":"Couldn't get file name of current executable.","messagePattern":"Couldn't get file name of current executable\\.","errorType":"exception","errorClass":"std::io::Error (NotFound)","httpStatus":null,"severity":"error","filePath":"backend/tauri-plugin-deep-link/src/linux.rs","lineNumber":90,"sourceCode":"                &format!(\"x-scheme-handler/{}\", scheme),\n            ])\n            .status()?;\n    }\n\n    Ok(())\n}\n\npub fn unregister(_schemes: &[&str]) -> Result<()> {\n    let mut target =\n        data_dir().ok_or_else(|| Error::new(ErrorKind::NotFound, \"data directory not found.\"))?;\n\n    target.push(\"applications\");\n\n    target.push(format!(\n        \"{}-handler.desktop\",\n        tauri_utils::platform::current_exe()?\n            .file_name()\n            .ok_or_else(|| Error::new(\n                ErrorKind::NotFound,\n                \"Couldn't get file name of current executable.\",\n            ))?\n            .to_string_lossy()\n    ));\n\n    remove_file(&target)?;\n    target.pop();\n\n    Ok(())\n}\n\npub fn listen<F: FnMut(String) + Send + 'static>(mut handler: F) -> Result<()> {\n    std::thread::spawn(move || {\n        let addr = format!(\n            \"/tmp/{}-deep-link.sock\",\n            ID.get().expect(\"listen() called before prepare()\")\n        );","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri-plugin-deep-link/src/linux.rs#L72-L108","documentation":"During `unregister` on Linux, the plugin derives the `.desktop` handler file name from the current executable's file name via `tauri_utils::platform::current_exe()`. If the exe path has no final component (e.g. path is `/`, `..`, or otherwise unusual), `file_name()` returns None and this `NotFound` error is thrown.","triggerScenarios":"Calling `unregister` when `std::env::current_exe()` resolves to a path whose `file_name()` is None — a path ending in `..`, a deleted/replaced executable, or exotic mount setups where the exe path is a bare root.","commonSituations":"App launched through a symlink chain that got replaced, running from a path like `/proc/self/exe`-style tricks in sandboxes (Flatpak/firejail), or the binary being deleted while running (upgrades), causing resolution oddities.","solutions":["Ensure the app is launched from a normal file path (not a root-like or dotted path).","Verify the executable still exists on disk after upgrades before unregistering.","Catch ErrorKind::NotFound from unregister and log it instead of failing the shutdown path."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let exe = std::env::current_exe()?;\nif exe.file_name().is_none() {\n    log::warn!(\"current exe path has no file name; skip unregister\");\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = unregister(&[\"myapp\"]) {\n    if e.kind() == std::io::ErrorKind::NotFound { log::warn!(\"skip: {e}\"); } else { return Err(e.into()); }\n}","preventionTips":["Launch the app from a normal filesystem path","Avoid unregistering while the binary is being replaced/upgraded","Check std::env::current_exe().file_name() early in shutdown code"],"tags":["linux","filesystem","deep-link","executable-path"],"backgroundTag":"file-not-found","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}