libnyanpasu/clash-nyanpasu · error
config path is not UTF-8: {}
Error message
config path is not UTF-8: {} What it means
This error is thrown by `utf8_path` when converting a `PathBuf` into `Utf8PathBuf` fails, i.e. the config file path contains bytes that are not valid UTF-8. On Windows, paths are UTF-16 and may contain unpaired surrogates; on Unix they may be arbitrary bytes. The client requires UTF-8 paths because config paths are passed through typed `Utf8PathBuf` values (serde/IPC-friendly).
Source
Thrown at backend/tauri/src/client/mod.rs:1340
pub async fn rebuild_running_config(&self) -> Result<()> {
self.reconcile_core()
.await
.map_err(client_error_from_core)?;
self.inner.ui_sink.refresh_clash();
Ok(())
}
pub(crate) async fn regenerate_runtime(&self) -> Result<()> {
self.reconcile_core()
.await
.map(|_| ())
.map_err(client_error_from_core)
}
}
fn utf8_path(path: PathBuf) -> anyhow::Result<Utf8PathBuf> {
Utf8PathBuf::from_path_buf(path)
.map_err(|path| anyhow::anyhow!("config path is not UTF-8: {}", path.display()))
}
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use crate::state::{
mirror::{
ClashLegacyBridge, NoopPreparedLegacyMirror, PreparedLegacyMirror, VergeLegacyBridge,
WindowLegacyBridge,
},
profiles::ports::{
CleanupOutcome, MaterializationReconcileReport, MockProfileFsPort,
MockProfileMaterializationPort, MockRebuildNotifier, MockSubscriptionFetcher,
PreparedCleanup, PreparedMaterialization, ProfileMaterializationPort,
},
};
use camino::Utf8PathBuf;
use nyanpasu_config::{View on GitHub (pinned to f7dbce2997)
Solutions
- Rename the config directory/file (or the user profile path) so it contains only valid UTF-8 characters
- Check the path with `Path::to_str()` before calling the API to detect the offending bytes
- Re-encode/recover the path via `String::from_utf8` on the raw bytes to find which component is invalid
- If on Windows, ensure the path is retrieved via UTF-8-safe APIs (`to_string_lossy` only masks the problem)
Example fix
// before
let path = std::env::var("CONFIG_PATH").unwrap(); // may carry non-UTF-8 bytes on some platforms
client.load_config(PathBuf::from(path)).await?;
// after
let path = std::env::var_os("CONFIG_PATH").unwrap();
if path.to_str().is_none() {
eprintln!("CONFIG_PATH is not valid UTF-8: {:?}", path);
return;
}
client.load_config(PathBuf::from(path)).await?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_utf8(path: &std::path::Path) -> Result<(), String> {
match path.to_str() {
Some(_) => Ok(()),
None => Err(format!("path is not valid UTF-8: {:?}", path.as_os_str())),
}
} Type guard
fn is_utf8_path(path: &std::path::Path) -> bool {
path.to_str().is_some()
} Prevention
- Always resolve config paths through UTF-8-checked APIs before passing them to the client
- Avoid non-ASCII/special characters in app data directory names
- On Linux, keep LANG/LC_ALL set to a UTF-8 locale so user dirs are UTF-8 encoded
- Log `path.as_os_str()` (not the lossy string) when reporting path failures
When it happens
Trigger: Calling any client config API (e.g. loading/patching a config file at backend/tauri/src/client/mod.rs:1340) where the resolved config path was constructed from an environment with non-UTF-8 characters — e.g. a user profile directory, home dir, or `--config` argument containing legacy-encoded bytes.
Common situations: Windows usernames or home directories with characters outside the system's UTF-8 conversion (CJK/emoji/legacy codepage names); Linux systems with filenames in non-UTF-8 locale encodings; paths built from raw OS strings read from the environment.
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
- runtime path is not UTF-8: {}
- path is not valid UTF-8: {}
- non-UTF-8 source
- non-UTF-8 destination
- failed to get app_path
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/7f0aa462fe6a21fa.
Report an issue: GitHub.