{"record":{"id":"20394c91fcc3ecc5","repo":"jdx/mise","slug":"option-name-must-be-a-plain-file-name-no-p","errorCode":null,"errorMessage":"{option}: '{name}' must be a plain file name (no path separators or parent directories)","messagePattern":"(.+?): '(.+?)' must be a plain file name \\(no path separators or parent directories\\)","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/backend/static_helpers.rs","lineNumber":1133,"sourceCode":"        p.file_name()\n            .map(|n| {\n                let name = n.to_string_lossy();\n                !should_skip_file(&name, true) && glob.matches(&name)\n            })\n            .unwrap_or(false)\n    }) {\n        return Ok(Some(available.remove(idx)));\n    }\n\n    Ok(None)\n}\n\n/// Rejects `bin`/`rename_exe` names that are not plain file names (`../tool`,\n/// `/abs/tool`, `bin/tool`), which would otherwise be joined onto the install\n/// or search directory and place the binary outside it.\npub fn ensure_plain_bin_name(option: &str, name: &str) -> eyre::Result<()> {\n    if !file::is_plain_file_name(name) {\n        bail!(\n            \"{option}: '{name}' must be a plain file name \\\n             (no path separators or parent directories)\"\n        );\n    }\n    Ok(())\n}\n\n/// Rejects a configured binary path that is absolute or contains parent\n/// components, while preserving the established `bin = \"bin/tool\"` form.\npub fn ensure_safe_relative_bin_path(option: &str, path: &str) -> eyre::Result<()> {\n    if !file::is_safe_relative_path(path) {\n        bail!(\n            \"{option}: '{path}' must be a safe relative path \\\n             (no absolute paths or parent directories)\"\n        );\n    }\n    Ok(())\n}","sourceCodeStart":1115,"sourceCodeEnd":1151,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/backend/static_helpers.rs#L1115-L1151","documentation":"mise validates that the `rename_exe` (and similar) backend option is a single plain file name before joining it onto the install directory. The guard `file::is_plain_file_name` rejects any value containing `/` or `\\\\`, or any parent/root/drive component, because such a value would place or find the binary outside the install dir (path traversal). It is thrown during install/setup of static-binary backends (ubi, http, aqua-style) when the option is first read.","triggerScenarios":"A mise.toml `[tools]` entry with e.g. `rename_exe = \"../tool\"`, `rename_exe = \"/usr/local/bin/tool\"`, or `rename_exe = \"bin/tool\"` (any path with separators) for a backend that calls ensure_plain_bin_name (src/backend/static_helpers.rs:591, :1048, :1087; src/backend/http.rs:409). The error surfaces as soon as the tool version is installed or the option is parsed.","commonSituations":"Copy-pasting a `bin = \"bin/tool\"` style value into `rename_exe` (the two options have different rules); migrating from a backend that allowed paths; trying to rename into a subdirectory of the install dir; values copied from Windows configs with backslashes.","solutions":["Set rename_exe to a plain file name only, e.g. rename_exe = \"tool\" — directories belong in the `bin` option (bin = \"bin/tool\"), not in rename_exe","If you need the binary at a nested path, keep the nested path in `bin` and use rename_exe only for the final name change","Remove any leading ./ , ../ , or absolute path from the value; both `/` and `\\\\` are rejected on every platform"],"exampleFix":"# before (mise.toml)\n[tools.ubi]\nmytool = { repo = 'org/mytool', rename_exe = 'bin/mytool-renamed' }\n\n# after\n[tools.ubi]\nmytool = { repo = 'org/mytool', bin = 'bin/', rename_exe = 'mytool-renamed' }","handlingStrategy":"validation","validationCode":"# Rust: same rule mise enforces (see file::is_plain_file_name)\nfn is_plain_bin_name(s: &str) -> bool {\n    !s.is_empty()\n        && !s.contains('/')\n        && !s.contains('\\\\')\n        && std::path::Path::new(s).components().next()\n            .map(|c| matches!(c, std::path::Component::Normal(_)))\n            .unwrap_or(false)\n}\nassert!(is_plain_bin_name(\"tool\"));\nassert!(!is_plain_bin_name(\"bin/tool\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep rename_exe values as bare file names; never paste paths","Reserve subdirectory routing for the `bin` option","Lint mise.toml entries (regex ^[^/\\\\]+$ for rename_exe) in CI before install"],"tags":["mise","config-validation","path-traversal","backend","rename-exe"],"backgroundTag":"config-validation-failed","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}