libnyanpasu/clash-nyanpasu · error

failed to copy core: {status}

Error message

failed to copy core: {status}

What it means

After attempting an elevated (runas) copy of the core binary (cmd /C copy /Y on Windows, cp -f elsewhere), the adapter checks the child process's exit status. If the elevation request was denied or the copy failed (non-zero exit), anyhow::ensure! throws "failed to copy core: {status}" including the ExitStatus. This is the generic failure of the privilege-escalation fallback for installing the core executable.

Source

Thrown at backend/tauri/src/client/core_lifecycle/adapters.rs:59

                                source,
                                destination.trim_start_matches(r"\\?\"),
                            ])
                            .status()?,
                    )
                }
                #[cfg(not(target_os = "windows"))]
                {
                    Ok::<_, anyhow::Error>(
                        runas::Command::new("cp")
                            .arg("-f")
                            .arg(source)
                            .arg(destination)
                            .status()?,
                    )
                }
            })
            .await??;
            anyhow::ensure!(status.success(), "failed to copy core: {status}");
        }
        Ok(())
    }
}

pub(in crate::client) struct FsRuntimeBuildAdapter {
    pub profiles_dir: PathBuf,
    pub paths: runtime::RuntimePaths,
    pub ports: Arc<SessionPortResolver>,
}

#[async_trait]
impl RuntimeBuildPort for FsRuntimeBuildAdapter {
    fn core_spec(
        &self,
        core: &nyanpasu_config::application::ClashCore,
    ) -> anyhow::Result<nyanpasu_core_manager::CoreSpec> {
        super::super::runtime_core_spec(core)

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Stop the running core process (or the app) before retrying installation so the destination file is not locked.
  2. Re-run the install and accept the UAC/admin prompt; ensure the account can elevate.
  3. Check destination permissions/locks (open handles, antivirus) and free or unlock the target path.
  4. Check the ExitStatus in the message to identify the OS error code, and manually copy the staged binary to the destination as administrator.

Example fix

// before: retrying install while the core is still running
installer.install(&artifact).await?; // fails: destination locked, elevated copy denied
// after
core_client.restart_core().await?; // or stop the core first
tokio::time::sleep(Duration::from_millis(500)).await;
installer.install(&artifact).await?;
Defensive patterns

Strategy: retry

Validate before calling

async fn destination_writable(p: &std::path::Path) -> bool {
    match p.parent() {
        Some(dir) => tokio::fs::metadata(dir).map(|m| m.is_dir()).await.unwrap_or(false)
            && std::fs::OpenOptions::new().append(true).open(p).is_ok(),
        None => false,
    }
}

Type guard

fn copy_failed(status: &std::process::ExitStatus) -> bool { !status.success() }

Try / catch

match installer.install(&artifact).await {
    Err(e) if e.to_string().contains("failed to copy core") => {
        tracing::warn!("elevated copy failed; stopping core and retrying once");
        core_client.stop_core().await?;
        installer.install(&artifact).await.context(
            "core copy failed even after elevation; unlock the destination or grant admin rights"
        )?;
    }
    Ok(()) => {},
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling FsBinaryInstaller::install when the direct tokio::fs::copy failed (e.g. permission denied on the destination) and the subsequent elevated copy fails: user cancels the UAC prompt, lacks admin rights, the destination is read-only/locked by a running core process, or cmd/cp exits with an error.

Common situations: Updating the mihomo/clash core while the core process is still running and locking the file; UAC elevation declined by the user; installing into Program Files without admin; antivirus blocking the copy.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/d0b0bba487df67cb. Report an issue: GitHub.