{"record":{"id":"3b3409ed2b8e3ff8","repo":"Schniz/fnm","slug":"path-is-not-valid-utf-8","errorCode":null,"errorMessage":"Path is not valid UTF-8","messagePattern":"Path is not valid UTF-8","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/shell/zsh.rs","lineNumber":18,"sourceCode":"use crate::version_file_strategy::VersionFileStrategy;\n\nuse super::shell::Shell;\nuse indoc::formatdoc;\nuse std::path::Path;\n\n#[derive(Debug)]\npub struct Zsh;\n\nimpl Shell for Zsh {\n    fn to_clap_shell(&self) -> clap_complete::Shell {\n        clap_complete::Shell::Zsh\n    }\n\n    fn path(&self, path: &Path) -> anyhow::Result<String> {\n        let path = path\n            .to_str()\n            .ok_or_else(|| anyhow::anyhow!(\"Path is not valid UTF-8\"))?;\n        let path =\n            super::windows_compat::maybe_fix_windows_path(path).unwrap_or_else(|| path.to_string());\n        Ok(format!(\"export PATH={path:?}:$PATH\"))\n    }\n\n    fn set_env_var(&self, name: &str, value: &str) -> String {\n        format!(\"export {name}={value:?}\")\n    }\n\n    fn rehash(&self) -> Option<&'static str> {\n        Some(\"rehash\")\n    }\n\n    fn use_on_cd(&self, config: &crate::config::FnmConfig) -> anyhow::Result<String> {\n        let version_file_exists_condition = if config.resolve_engines() {\n            \"-f .node-version || -f .nvmrc || -f package.json\"\n        } else {\n            \"-f .node-version || -f .nvmrc\"","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/Schniz/fnm/blob/86adc9676ceb2a509b21e75e74048b93c89f097d/src/shell/zsh.rs#L1-L36","documentation":"fnm's Zsh shell integration renders `export PATH=<dir>:$PATH` from a `&Path` in `Shell::path`. `Path::to_str()` returns None when the path is not valid UTF-8, and that None becomes this anyhow error during shell-setup generation such as `fnm env --shell zsh` or `fnm use`.","triggerScenarios":"Running `fnm env --shell zsh` (or any zsh PATH rendering) when the multishell path / base dir — FNM_MULTISHELL_PATH, FNM_DIR, or the XDG runtime/cache dir it derives from — contains invalid UTF-8 bytes.","commonSituations":"`.zshrc` exporting FNM_DIR with non-UTF-8 bytes (file saved in a legacy encoding); XDG_RUNTIME_DIR or XDG_CACHE_HOME pointing at a byte-mangled path; macOS usernames with legacy-encoded characters; leftover multishell symlinks with invalid names.","solutions":["Validate candidate vars: `for v in FNM_DIR FNM_MULTISHELL_PATH XDG_RUNTIME_DIR XDG_CACHE_HOME; do printf '%s' \"${(P)v}\" | iconv -f UTF-8 -t UTF-8 >/dev/null || echo \"$v: invalid UTF-8\"; done`.","Set clean values: `export FNM_DIR=\"$HOME/.local/share/fnm\"; unset FNM_MULTISHELL_PATH` and restart the shell.","Fix LANG/LC_ALL to a UTF-8 locale so system tools generate UTF-8 names.","Remove stale multishell symlinks in the fnm multishells storage so fresh, valid ones are created."],"exampleFix":"# before\nexport FNM_DIR=$'/data/b\\xffnm'\nfnm env --shell zsh   # error: Path is not valid UTF-8\n\n# after\nunset FNM_DIR\nexport FNM_DIR=\"$HOME/.local/share/fnm\"\nfnm env --shell zsh   # export PATH=... emitted","handlingStrategy":"validation","validationCode":"fn fnm_paths_are_utf8() -> bool {\n    [\"FNM_DIR\", \"FNM_MULTISHELL_PATH\", \"XDG_RUNTIME_DIR\", \"XDG_CACHE_HOME\"]\n        .iter()\n        .filter_map(std::env::var_os)\n        .all(|v| v.to_str().is_some())\n}","typeGuard":"fn is_utf8_path(p: &std::path::Path) -> bool {\n    p.to_str().is_some()\n}","tryCatchPattern":"match zsh_shell.path(&multishell_dir) {\n    Ok(line) => println!(\"{line}\"),\n    Err(e) => eprintln!(\"fnm env failed; FNM paths must be UTF-8: {e}\"),\n}","preventionTips":["Export FNM_DIR from a UTF-8 .zshrc using a plain literal.","Check XDG_* dirs for stray bytes after migrations or restores.","Use `iconv` validation in bootstrap scripts before sourcing fnm env."],"tags":["rust","path","utf-8","zsh","fnm-env","anyhow"],"backgroundTag":"non-utf8-path","analyzedSha":"86adc9676ceb2a509b21e75e74048b93c89f097d","analyzedAt":"2026-08-16T21:43:05.725Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}