{"record":{"id":"e3abcb2872ff2666","repo":"jdx/mise","slug":"invalid-tool-path-s-extended-length-and-devic-e3abcb","errorCode":null,"errorMessage":"invalid tool path {s:?}: extended-length and device paths (\\\\?\\, \\\\.\\) are not supported","messagePattern":"invalid tool path (.+?): extended-length and device paths \\(\\\\\\\\\\?\\\\, \\\\\\\\\\.\\\\\\) are not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/toolset/tool_request.rs","lineNumber":777,"sourceCode":"/// The list is written for a POSIX shell, which is why `\\` is on it. On Windows `\\` is a path\n/// separator instead, so it is rewritten by [`windows_path_separators`] before it gets here rather\n/// than being allowed through — see that function. The shell those hooks run through there is\n/// `cmd.exe`, whose metacharacters are a different set, so a few more are rejected on Windows —\n/// see [`is_forbidden_path_char`].\nfn validate_path_string(s: &str) -> Result<()> {\n    if s.is_empty() {\n        return Ok(());\n    }\n    if let Some(c) = s.chars().find(|c| {\n        // Allow newlines/tabs/etc. in paths is still bad — keep control-char\n        // and quote/expansion rejection, but allow `/` since paths need it.\n        is_forbidden_path_char(*c)\n    }) {\n        // The only `\\` that survives the rewrite is an extended-length or device prefix, so say\n        // what is actually wrong instead of naming a character the user cannot avoid.\n        #[cfg(windows)]\n        if c == '\\\\' {\n            bail!(\n                \"invalid tool path {s:?}: extended-length and device paths (\\\\\\\\?\\\\, \\\\\\\\.\\\\) are not supported\"\n            );\n        }\n        bail!(\"invalid tool path {s:?}: contains forbidden character {c:?}\");\n    }\n    Ok(())\n}\n\n/// Rewrite `\\` to `/` in a `path:` value on Windows.\n///\n/// `\\` is the path separator there, not a shell metacharacter, so [`validate_path_string`] used to\n/// reject every native path — anything copied out of Explorer or printed by `pwd`. Win32 accepts\n/// `/` wherever it accepts `\\`, so rewriting is what makes those usable *without* letting a `\\`\n/// reach a vfox hook's `ctx.rootPath`, which is the thing the list exists to prevent (#9814). The\n/// alternative — dropping `\\` from the list on Windows — would have weakened that.\n///\n/// Extended-length and device prefixes (`\\\\?\\`, `\\\\.\\`) are left alone. Those are the one place\n/// Windows does not accept `/`, so rewriting would hand back a path that looks right and does not","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/toolset/tool_request.rs#L759-L795","documentation":"On Windows, a path: tool value may not use extended-length (\\\\?\\) or device (\\\\.\\) path prefixes. Backslashes are rewritten to '/' and the only surviving '\\' is such a prefix, so validate_path_string reports the prefix problem explicitly instead of a confusing forbidden-character message.","triggerScenarios":"On Windows, passing a path: value like \\\\?\\C:\\tools\\foo or \\\\.\\pipe\\... through new_with_options; after backslash rewriting, the leading '\\' characters remain and hit the windows-only bail.","commonSituations":"Copying a path obtained from Windows APIs (many return \\\\?\\-prefixed paths) into mise.toml; long paths auto-normalized by other tooling; UNC/device paths pasted from PowerShell.","solutions":["Strip the \\\\?\\ or \\\\.\\ prefix and use a plain absolute path, e.g. path:C:/tools/foo.","Use forward slashes (mise rewrites them anyway) and avoid UNC device syntax.","If the path exceeds MAX_PATH, use a short path (GetShortPathName) or a directory junction instead of the extended-length prefix."],"exampleFix":"// mise.toml (Windows) before\nnode = \"path:\\\\\\?\\C:\\tools\\node\"\n// after\nnode = \"path:C:/tools/node\"","handlingStrategy":"validation","validationCode":"function validPath(p) {\n  return typeof p === 'string' && !p.startsWith('\\\\\\\\?\\\\') && !p.startsWith('\\\\\\\\.\\\\');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Strip \\\\?\\ / \\\\.\\ prefixes returned by Windows APIs before storing paths.","Use forward slashes in mise.toml paths on Windows.","Keep project directories shallow enough to avoid MAX_PATH issues."],"tags":["mise","windows","validation","path"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}