{"record":{"id":"77d202bca49999a6","repo":"Schniz/fnm","slug":"can-t-join-paths-err","errorCode":null,"errorMessage":"Can't join paths: {err}","messagePattern":"Can't join paths: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/shell/windows_cmd/mod.rs","lineNumber":19,"sourceCode":"use super::shell::Shell;\nuse std::path::Path;\n\n#[derive(Debug)]\npub struct WindowsCmd;\n\nimpl Shell for WindowsCmd {\n    fn to_clap_shell(&self) -> clap_complete::Shell {\n        // TODO: move to Option\n        panic!(\"Shell completion is not supported for Windows Command Prompt. Maybe try using PowerShell for a better experience?\");\n    }\n\n    fn path(&self, path: &Path) -> anyhow::Result<String> {\n        let current_path =\n            std::env::var_os(\"path\").ok_or_else(|| anyhow::anyhow!(\"Can't read PATH env var\"))?;\n        let mut split_paths: Vec<_> = std::env::split_paths(&current_path).collect();\n        split_paths.insert(0, path.to_path_buf());\n        let new_path = std::env::join_paths(split_paths)\n            .map_err(|err| anyhow::anyhow!(\"Can't join paths: {err}\"))?;\n        let new_path = new_path\n            .to_str()\n            .ok_or_else(|| anyhow::anyhow!(\"Can't convert path to string\"))?;\n        Ok(format!(\"SET PATH={new_path}\"))\n    }\n\n    fn set_env_var(&self, name: &str, value: &str) -> String {\n        format!(\"SET {name}={value}\")\n    }\n\n    fn use_on_cd(&self, config: &crate::config::FnmConfig) -> anyhow::Result<String> {\n        let path = config.base_dir_with_default().join(\"cd.cmd\");\n        create_cd_file_at(&path).map_err(|source| {\n            anyhow::anyhow!(\n                \"Can't create cd.cmd file for use-on-cd at {}: {}\",\n                path.display(),\n                source\n            )","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/Schniz/fnm/blob/86adc9676ceb2a509b21e75e74048b93c89f097d/src/shell/windows_cmd/mod.rs#L1-L37","documentation":"WindowsCmd's `Shell::path` splits the existing PATH, inserts fnm's bin dir at index 0, and rejoins with `std::env::join_paths`. Rejoining fails when any single entry contains the Windows path separator `;` (or `:` on Unix) inside itself, and the io::Error is wrapped into this anyhow error.","triggerScenarios":"`fnm env --shell cmd` when one PATH entry embeds a literal `;` in a directory name — e.g. `set PATH=C:\\tools\\a;b;%PATH%` without quoting — making the element unencodable in a joined PATH.","commonSituations":"Batch scripts appending unquoted paths containing semicolons; folders literally named with `;` (legal on NTFS); registry PATH edits that lost quotes around `C:\\Program Files`-style entries with extra semicolons; ported Unix scripts leaving `:` entries.","solutions":["Print PATH raw (`echo %PATH%` or `reg query \"HKCU\\Environment\" /v Path`) and spot entries that contain an internal `;`.","Fix the entry: quote it in the registry (System Properties → Environment Variables) or rename the folder without `;`.","Replace the malformed entry with two properly separated entries.","Re-run `fnm env --shell cmd`."],"exampleFix":":: before\nset PATH=C:\\tools\\a;b;%PATH%\nfnm env --shell cmd   :: error: Can't join paths\n\n:: after\nset PATH=C:\\tools\\a;C:\\tools\\b;%PATH%\nfnm env --shell cmd   :: ok","handlingStrategy":"validation","validationCode":"fn path_is_joinable() -> bool {\n    let sep = if cfg!(windows) { ';' } else { ':' };\n    std::env::var_os(\"path\")\n        .map(|p| std::env::split_paths(&p).all(|e| !e.as_os_str().to_string_lossy().contains(sep)))\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match cmd_shell.path(&dir) {\n    Ok(out) => out,\n    Err(e) if e.to_string().contains(\"join paths\") =>\n        eprintln!(\"malformed PATH entry containing ';' — clean it and retry: {e}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Quote paths with special characters when appending to PATH in batch scripts.","Rename directories so no PATH element contains ';'.","Verify PATH shape (`echo %PATH%`) after installer runs."],"tags":["rust","cmd","windows","path","path-separator","join-paths"],"backgroundTag":"invalid-path-separator","analyzedSha":"86adc9676ceb2a509b21e75e74048b93c89f097d","analyzedAt":"2026-08-16T21:43:05.725Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}