{"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":null,"httpStatus":null,"severity":"error","filePath":"src/backend/static_helpers.rs","lineNumber":1198,"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(crate) 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(crate) 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":1180,"sourceCodeEnd":1216,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/backend/static_helpers.rs#L1180-L1216","documentation":"mise rejects bin/rename_exe values that are not plain file names. Path separators or parent-directory components would let the joined output land outside the install or search directory, so ensure_plain_bin_name bails before any file operation. This is a safety guard against writing binaries to unexpected locations.","triggerScenarios":"Calling dest_filename, windows_script_launcher, install_artifact, or apply_rename_exe with a bin or rename_exe value containing '/', '\\\\', or '..' (e.g. '../tool', '/abs/tool', 'bin/tool') in tool config.","commonSituations":"Tool authors copying a repo-relative path into the bin field, absolute paths pasted from local machines, or Windows-style paths with backslashes.","solutions":["Change the bin/rename_exe value to just the file name and configure any subdirectory separately via the path option that supports relative paths","If the binary lives in a subdirectory, use the config option that accepts a safe relative path (validated by ensure_safe_relative_bin_path) instead","Verify no template expansion is injecting slashes into the name"],"exampleFix":"# before\n[bin]\nrename_exe = \"bin/mytool\"\n# after\n[bin]\nrename_exe = \"mytool\"","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn assert_plain_name(opt: &str, name: &str) -> Result<(), String> {\n    if name.is_empty() || name.contains('/') || name.contains('\\\\') || name.contains(\"..\") {\n        return Err(format!(\"{opt}: {name:?} must be a plain file name\"));\n    }\n    Ok(())\n}","typeGuard":"fn is_plain_file_name(name: &str) -> bool {\n    !name.is_empty() && !name.contains('/') && !name.contains('\\\\') && !name.contains(\"..\")\n}","tryCatchPattern":null,"preventionTips":["Use bare file names in bin/rename_exe","Never build these values from paths or URLs","Sanitize templated values before config use"],"tags":["validation","path-safety","config"],"backgroundTag":"path-traversal-blocked","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"}