libnyanpasu/clash-nyanpasu · error

runtime path is not UTF-8: {}

Error message

runtime path is not UTF-8: {}

What it means

`RuntimePaths::utf8_path` fails when a runtime-related path (config dir, product file, etc.) cannot be represented as `Utf8PathBuf`, i.e. it contains non-UTF-8 bytes. `RuntimePaths::from_resolver` requires UTF-8 paths since they flow into typed, serializable structures.

Source

Thrown at backend/tauri/src/client/runtime.rs:304

fn is_symlink_or_reparse(metadata: &std::fs::Metadata) -> bool {
    metadata.file_type().is_symlink()
}

#[cfg(windows)]
fn is_symlink_or_reparse(metadata: &std::fs::Metadata) -> bool {
    use std::os::windows::fs::MetadataExt;
    const FILE_ATTRIBUTE_REPARSE_POINT: u32 = 0x400;
    metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0
}

#[cfg(not(any(unix, windows)))]
fn is_symlink_or_reparse(metadata: &std::fs::Metadata) -> bool {
    metadata.file_type().is_symlink()
}

fn utf8_path(path: std::path::PathBuf) -> anyhow::Result<Utf8PathBuf> {
    Utf8PathBuf::from_path_buf(path)
        .map_err(|path| anyhow::anyhow!("runtime path is not UTF-8: {}", path.display()))
}

/// Public mutation wire (PR-4S S08 / plan §12): state is committed first; post-
/// commit side-effect failures degrade instead of erroring.
///
/// Final wire is only `applied` / `committed_degraded` — no `_v1` alias.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, specta::Type)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum MutationOutcome<T> {
    Applied {
        value: T,
    },
    CommittedDegraded {
        value: T,
        degradations: Vec<Degradation>,
    },
}

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Move the app data/runtime directory to a path containing only valid UTF-8 characters
  2. Fix the environment variables (HOME/XDG_CONFIG_HOME and equivalents) that resolve to the non-UTF-8 path
  3. Identify the offending component with `path.to_str()` / `to_string_lossy` and rename it
  4. On Windows, use UTF-8-safe APIs when choosing the install/data location

Example fix

// before
export HOME="/home/$(printf '\xff\xfe')" # non-UTF-8 home breaks path resolution
./nyanpasu
// after
export HOME="/home/user" # ensure UTF-8-safe directories
./nyanpasu
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_utf8(path: &std::path::Path) -> Result<(), String> {
    if path.to_str().is_some() { Ok(()) } else { Err(format!("non-UTF-8 runtime path: {:?}", path.as_os_str())) }
}
// run on the resolver output before building RuntimePaths

Type guard

fn is_utf8_path(path: &std::path::Path) -> bool {
    path.to_str().is_some()
}

Prevention

When it happens

Trigger: Building `RuntimePaths::from_resolver` (backend/tauri/src/client/runtime.rs:304) when the OS-resolved runtime directory or file name contains non-UTF-8 bytes — typically a non-UTF-8 user home or data directory.

Common situations: Linux systems where `$HOME` or XDG data dirs contain legacy-encoded bytes; Windows profiles with unpaired surrogate characters; portable installs placed in a non-UTF-8 folder name.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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