{"record":{"id":"645b019ccacb09f4","repo":"libnyanpasu/clash-nyanpasu","slug":"failed-to-get-core-dir","errorCode":null,"errorMessage":"failed to get core dir","messagePattern":"failed to get core dir","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/core/updater/instance.rs","lineNumber":230,"sourceCode":"        tracing::debug!(\"writing core to {:?} ({} bytes)\", tmp_core, buff.len());\n        let mut core_file = tokio::fs::File::create(&tmp_core).await?;\n        tokio::io::copy(&mut buff.as_slice(), &mut core_file).await?;\n        #[cfg(target_family = \"unix\")]\n        {\n            std::fs::set_permissions(&tmp_core, std::fs::Permissions::from_mode(0o755))?;\n        }\n        Ok(())\n    }\n\n    async fn replace_core(&self) -> anyhow::Result<()> {\n        self.dispatch_state(UpdaterState::Replacing);\n\n        #[cfg(target_os = \"windows\")]\n        let target_core = format!(\"{}.exe\", self.core_type);\n        #[cfg(not(target_os = \"windows\"))]\n        let target_core = self.core_type.clone().to_string();\n        let core_dir = tauri::utils::platform::current_exe()?;\n        let core_dir = core_dir.parent().ok_or(anyhow!(\"failed to get core dir\"))?;\n        let target_core = core_dir.join(target_core);\n        let tmp_core_path = self.temp_dir.path().join(format!(\n            \"{}{}\",\n            self.core_type,\n            std::env::consts::EXE_SUFFIX\n        ));\n\n        self.nyanpasu\n            .replace_core_binary(crate::client::core_lifecycle::ports::PreparedCoreBinary {\n                target: self.core_type,\n                source: tmp_core_path,\n                destination: target_core,\n                staging: self.temp_dir.clone(),\n                progress: Arc::new(UpdaterInstallProgress(self.inner.clone())),\n            })\n            .await?;\n\n        Ok(())","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/core/updater/instance.rs#L212-L248","documentation":"During a core update, replace_core locates the directory of the running executable via current_exe() and takes its parent as the core install directory. If current_exe() returns a root-level path with no parent directory, the error is thrown and the core binary cannot be replaced in place.","triggerScenarios":"Calling start -> replace_core when the app executable sits at a filesystem root (e.g. '/nyanpasu' where parent exists but root '/' where it doesn't, or deleted cwd scenarios) so core_dir.parent() returns None.","commonSituations":"Running the binary from a drive root on Windows (C:\\nyanpasu.exe -> parent C:\\ exists, but exotic sandbox/mount setups can yield parentless paths), containerized or chroot environments, or a deleted/renamed install directory.","solutions":["Install/run the app from a normal subdirectory, not a filesystem root","Log current_exe() output to confirm the resolved path before replacement","Fall back to a configured install directory instead of deriving it from current_exe"],"exampleFix":"// before\nlet core_dir = core_dir.parent().ok_or(anyhow!(\"failed to get core dir\"))?;\n// after\nlet core_dir = core_dir.parent().with_context(|| format!(\"current exe has no parent dir: {:?}\", core_dir))?;","handlingStrategy":"validation","validationCode":"let exe = tauri::utils::platform::current_exe()?;\nif exe.parent().is_none() {\n    eprintln!(\"cannot determine core dir: exe {:?} has no parent\", exe);\n}","typeGuard":"fn exe_parent_dir() -> Option<std::path::PathBuf> {\n    tauri::utils::platform::current_exe().ok()?.parent().map(|p| p.to_path_buf())\n}","tryCatchPattern":"match replace_core(/* ... */).await {\n    Ok(n) => n,\n    Err(e) if e.to_string().contains(\"failed to get core dir\") => /* abort update, report unusable install location */,\n    Err(e) => return Err(e),\n}","preventionTips":["Install the app in a regular subdirectory, never at a filesystem root","Resolve and log the core directory at startup to catch layout problems early","Support a configurable core directory as a fallback to current_exe-derived paths"],"tags":["rust","filesystem","updater","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"}