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
- Install the app (or set the core destination) under a path with only UTF-8-representable characters and reinstall/redo the core install.
- Strip the \\?\ verbatim prefix and normalize the destination path before conversion, or use short path names for the cmd invocation.
- Use to_string_lossy with a logged warning when exact fidelity is acceptable, instead of hard-failing.
- 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
- Install the application into UTF-8-safe directories
- Normalize/strip \\?\ verbatim prefixes before invoking shell copies
- Log path lossiness early at startup so encoding issues surface before install time
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
- non-UTF-8 source
- path is not valid UTF-8: {}
- failed to get app_path
- managed profile path uses reserved private storage
- managed target is an unsupported reparse point: {}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/674af99a410444d9.
Report an issue: GitHub.