{"record":{"id":"19c18ba94349a8a5","repo":"jdx/mise","slug":"invalid-command-wrapper-name-name","errorCode":null,"errorMessage":"invalid command wrapper name: {name:?}","messagePattern":"invalid command wrapper name: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/shims.rs","lineNumber":1130,"sourceCode":"        a == b\n    }\n}\n\npub(crate) fn command_name_without_exe_suffix(bin_name: &str) -> &str {\n    let suffix = std::env::consts::EXE_SUFFIX;\n    if suffix.is_empty() {\n        return bin_name;\n    }\n    let suffix_start = bin_name.len().saturating_sub(suffix.len());\n    match (bin_name.get(..suffix_start), bin_name.get(suffix_start..)) {\n        (Some(name), Some(actual_suffix)) if actual_suffix.eq_ignore_ascii_case(suffix) => name,\n        _ => bin_name,\n    }\n}\n\nfn validate_wrapper_name(name: &str) -> Result<()> {\n    if name.is_empty() || name == \".\" || name == \"..\" || name.contains('/') || name.contains('\\\\') {\n        bail!(\"invalid command wrapper name: {name:?}\");\n    }\n    if cfg!(windows) && name.contains('.') {\n        bail!(\"command wrapper names cannot contain dots on Windows: {name:?}\");\n    }\n    Ok(())\n}\n\nfn validate_wrapper_names<'a>(names: impl IntoIterator<Item = &'a String>) -> Result<()> {\n    let mut normalized = HashSet::new();\n    for name in names {\n        validate_wrapper_name(name)?;\n        if cfg!(macos) && !normalized.insert(name.to_lowercase()) {\n            bail!(\"command wrapper names collide on macOS after case normalization: {name:?}\");\n        }\n    }\n    Ok(())\n}\n","sourceCodeStart":1112,"sourceCodeEnd":1148,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/shims.rs#L1112-L1148","documentation":"Command wrapper names must be valid, plain executable names: non-empty, not '.' or '..', and containing no path separators ('/' or '\\\\'). validate_wrapper_name rejects any name violating these rules because wrappers are keyed as command names, not paths.","triggerScenarios":"Declaring a wrapper key like `tools/mytool`, `sub\\dir\\cmd`, `.` or `..`, or an empty string in the command wrapper configuration (mise.toml wrapper section or `mise wrapper add` argument).","commonSituations":"Users pasting a file path where only the command name belongs, typos with trailing slashes, or generating wrapper names programmatically from paths without taking the basename.","solutions":["Use just the executable name as the wrapper key (e.g. `foo`, not `bin/foo`).","Strip the directory portion: use the basename of the path you intended.","If you meant to wrap a tool in a subdirectory, configure the wrapper's *command* with the full path and keep the name a plain identifier.","Fix empty/`.`/`..` entries by giving the wrapper an explicit name."],"exampleFix":"// before\n[wrapper]\n\"bin/ruff\" = \"ruff --fix\" // path separator invalid\n\n// after\n[wrapper]\nruff = \"/full/path/to/ruff --fix\"","handlingStrategy":"validation","validationCode":"// bash: validate a wrapper name before adding it\nvalidate_wrapper_name() {\n  case \"$1\" in\n    \"\"|.|..|*/*|*\\\\*) echo \"invalid wrapper name: $1\"; return 1;;\n    *) return 0;;\n  esac\n}\nvalidate_wrapper_name \"bin/ruff\" || echo 'use basename only'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrapper names are plain command names — strip paths to the basename.","Never use '.', '..', or names with / or \\\\.","Validate names in scripts that generate wrapper configs.","Put full paths in the wrapper's command, not its name."],"tags":["cli","validation","shims","config","rust"],"backgroundTag":"invalid-identifier-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}