libnyanpasu/clash-nyanpasu · critical · std::io::Error (NotFound)
{} not found
Error message
{} not found What it means
`find_binary_path` searches the known candidate locations for a clash core binary (mihomo/clash, selected by `CoreType`). If none of the candidates exist on disk it throws `NotFound` with the core's executable name, meaning the required core binary was never downloaded or placed.
Source
Thrown at backend/tauri/src/core/clash/mod.rs:20
use specta::Type;
use tauri_specta::Event;
pub mod api;
pub mod proxies;
pub mod ws;
// TODO: support system path search via a config or flag
// FIXME: move this fn to nyanpasu-utils
/// Search the binary path of the core. See [`binary_candidates`] for the
/// search locations and their priority.
pub fn find_binary_path(
core_type: &nyanpasu_utils::core::CoreType,
) -> std::io::Result<std::path::PathBuf> {
binary_candidates(core_type)
.into_iter()
.find(|path| path.exists())
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("{} not found", core_type.get_executable_name()),
)
})
}
/// Candidate core binary paths in priority order: data dir -> install dir.
/// Dev builds additionally register the downloaded `externalBin` sidecars
/// (`<crate>/sidecar/`): unlike `tauri build`, where the bundler copies the
/// sidecars next to the executable stripping the target-triple suffix,
/// `tauri dev` copies nothing, so neither the app's exe dir nor Tauri's own
/// sidecar lookup can find the cores there.
fn binary_candidates(core_type: &nyanpasu_utils::core::CoreType) -> Vec<std::path::PathBuf> {
let name = core_type.get_executable_name();
let mut candidates = Vec::new();
if let Ok(data_dir) = crate::utils::dirs::app_data_dir() {
candidates.push(data_dir.join(name));
}View on GitHub (pinned to f7dbce2997)
Solutions
- Run the sidecar preparation step (e.g. `pnpm prepare:check`) to download the core binaries into backend/tauri/sidecar/.
- Verify the binary exists at the expected location and the core type matches what was downloaded (mihomo vs clash).
- Reinstall/repair the app so bundled sidecars are present.
- Check that the install directory is writable and the binary was not quarantined.
Defensive patterns
Strategy: validation
Validate before calling
let present = binary_candidates(&core_type).iter().any(|p| p.exists());
if !present {
anyhow::bail!("core binary for {:?} missing; run sidecar setup", core_type);
} Try / catch
match find_binary_path(&core_type) {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => prompt_core_download()?,
other => other?,
} Prevention
- Run sidecar download (pnpm prepare:check) after checkout/install
- Verify binaries exist at startup and show a download prompt
- Watch for antivirus quarantine of core executables
When it happens
Trigger: Calling `find_binary_path(CoreType::Mihomo)` (or Clash) when no candidate path returned by `binary_candidates` exists — the sidecar binary is missing, was not bundled, or lives in a non-default install dir.
Common situations: Fresh install where `pnpm prepare:check`/sidecar download was skipped, antivirus quarantined the core binary, upgrading the app without re-downloading cores, or running from a source checkout without sidecar/ populated.
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
- no matches found for core type: {:?}
- failed to get core version
- failed to execute sidecar command
- unimplemented!()
- IPC server is already initialized
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/b932beefee3479d8.
Report an issue: GitHub.