{"record":{"id":"dac1bb13b7d9253e","repo":"jdx/mise","slug":"windows-script-interpreter-interpreter-must-b","errorCode":null,"errorMessage":"windows_script_interpreter: {interpreter:?} must be a plain executable name","messagePattern":"windows_script_interpreter: (.+?) must be a plain executable name","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/backend/http.rs","lineNumber":995,"sourceCode":"            );\n            return None;\n        }\n        let file_algo = crate::backend::asset_matcher::detect_checksum_algorithm(\n            &get_filename_from_url(&checksum_url),\n        );\n        fetch_checksum_from_file(&checksum_url, &file_algo).await\n    }\n}\n\n#[cfg(any(windows, test))]\nfn windows_script_launcher(script: &Path, interpreter: &str) -> Result<(PathBuf, String)> {\n    ensure_plain_bin_name(\"windows_script_interpreter\", interpreter)?;\n    if interpreter.is_empty()\n        || !interpreter\n            .chars()\n            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '.' | '_' | '-'))\n    {\n        eyre::bail!(\"windows_script_interpreter: {interpreter:?} must be a plain executable name\");\n    }\n    let filename = script\n        .file_name()\n        .and_then(|filename| filename.to_str())\n        .ok_or_else(|| eyre::eyre!(\"Windows script launcher requires a UTF-8 file name\"))?;\n    ensure_plain_bin_name(\"windows script\", filename)?;\n    if filename.is_empty()\n        || !filename\n            .chars()\n            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '.' | '_' | '-'))\n    {\n        eyre::bail!(\"Windows script file name {filename:?} contains unsupported characters\");\n    }\n    let launcher = script.with_file_name(format!(\"{filename}.cmd\"));\n    let body = format!(\"@echo off\\r\\n{interpreter} \\\"%~dp0{filename}\\\" %*\\r\\n\");\n    Ok((launcher, body))\n}\n","sourceCodeStart":977,"sourceCodeEnd":1013,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/backend/http.rs#L977-L1013","documentation":"On Windows, the http backend can generate a .cmd launcher that invokes a downloaded script through the configured `windows_script_interpreter`. Because the interpreter string is interpolated directly into a batch file body (`@echo off ... {interpreter} ...`), it must be a plain executable name — non-empty, ASCII alphanumeric plus `.`, `_`, `-` only. Paths, arguments, spaces, or shell metacharacters would enable command injection or broken launchers, so they are rejected.","triggerScenarios":"A Windows install of an http: tool whose options set `windows_script_interpreter` to something like `C:\\\\Python\\\\python.exe`, `python -u`, `node --experimental-vm-modules`, or any string with slashes/spaces — windows_script_launcher() rejects it before writing the launcher.","commonSituations":"Users copying an interpreter path from other tooling config into mise; trying to pass interpreter flags; portable installs where the interpreter is not on PATH so a full path 'seems' necessary.","solutions":["Use a bare executable name that is on PATH, e.g. `windows_script_interpreter = \"python\"` or `\"node.exe\"`","Put the interpreter's directory on PATH (user/system env, or via mise env) instead of specifying a path","Pass flags via the script itself, not through the interpreter string"],"exampleFix":"# before (mise.toml)\n[tools.\"http://example.com/tool.py\"]\nwindows_script_interpreter = 'C:\\\\Python311\\\\python.exe'\n# after\n[tools.\"http://example.com/tool.py\"]\nwindows_script_interpreter = \"python\"","handlingStrategy":"validation","validationCode":"# windows config gate: interpreter must be a bare name\n[[ \"$interp\" =~ ^[A-Za-z0-9._-]+$ ]] || echo 'use a plain executable name like python'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use bare interpreter names (python, node.exe) and put their dirs on PATH","Never put paths or CLI flags in windows_script_interpreter","Pass interpreter flags inside the script, not the config"],"tags":["windows","script-launcher","command-injection","http-backend","input-validation"],"backgroundTag":"invalid-executable-name","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}