libnyanpasu/clash-nyanpasu · error

non-UTF-8 destination

Error message

non-UTF-8 destination

What it means

Same mechanism as the "non-UTF-8 source" error, but for the destination path of the elevated Windows copy: destination.to_str() returns None because the target path's OsStr is not valid UTF-8. The elevated cmd.exe /C copy invocation requires a &str, so installation aborts.

Source

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

#[async_trait]
impl BinaryInstaller for FsBinaryInstaller {
    async fn install(&self, artifact: &PreparedCoreBinary) -> anyhow::Result<()> {
        if let Err(error) = tokio::fs::copy(&artifact.source, &artifact.destination).await {
            tracing::warn!(%error, "core copy failed; requesting elevated installation");
            let source = artifact.source.clone();
            let destination = artifact.destination.clone();
            // The blocking task itself retains the staging files if its waiter dies.
            let staging = artifact.staging.clone();
            let status = tokio::task::spawn_blocking(move || {
                let _staging = staging;
                #[cfg(target_os = "windows")]
                {
                    let source = source
                        .to_str()
                        .ok_or_else(|| anyhow::anyhow!("non-UTF-8 source"))?;
                    let destination = destination
                        .to_str()
                        .ok_or_else(|| anyhow::anyhow!("non-UTF-8 destination"))?;
                    Ok::<_, anyhow::Error>(
                        runas::Command::new("cmd")
                            .args(&[
                                "/C",
                                "copy",
                                "/Y",
                                source,
                                destination.trim_start_matches(r"\\?\"),
                            ])
                            .status()?,
                    )
                }
                #[cfg(not(target_os = "windows"))]
                {
                    Ok::<_, anyhow::Error>(
                        runas::Command::new("cp")
                            .arg("-f")
                            .arg(source)

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Install the app (or set the core destination) under a path with only UTF-8-representable characters and reinstall/redo the core install.
  2. Strip the \\?\ verbatim prefix and normalize the destination path before conversion, or use short path names for the cmd invocation.
  3. Use to_string_lossy with a logged warning when exact fidelity is acceptable, instead of hard-failing.
  4. Route the elevated copy through a mechanism taking OsStr/PathBuf (e.g. PowerShell with explicit encoding) rather than cmd.exe string args.

Example fix

// before
let destination = destination.to_str().ok_or_else(|| anyhow::anyhow!("non-UTF-8 destination"))?;
// after
let destination = destination.to_str().map(str::to_owned).unwrap_or_else(|| {
    tracing::warn!("destination not UTF-8; using lossy path");
    destination.to_string_lossy().into_owned()
});
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_utf8_path(p: &std::path::Path) -> anyhow::Result<()> {
    anyhow::ensure!(p.to_str().is_some(), "destination is not valid UTF-8: {:?}", p);
    Ok(())
}

Type guard

fn valid_utf8_path(p: &std::path::Path) -> Option<&str> { p.to_str() }

Try / catch

if let Err(e) = installer.install(&artifact).await {
    if e.to_string().contains("non-UTF-8 destination") {
        tracing::warn!("install dir not UTF-8; falling back to short-path install");
        install_with_short_paths(&artifact).await?;
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling FsBinaryInstaller::install on Windows where artifact.destination (the install target, e.g. the install dir core path) contains non-UTF-8 bytes and the initial tokio::fs::copy failed, forcing the runas path.

Common situations: Application installed under a directory whose name comes from a non-UTF-8-encodable locale string, UNC paths with non-UTF-8 components, or a user-chosen install directory with legacy-codepage characters.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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