jdx/mise · error · eyre::Report

Windows script file name {filename:?} contains unsupported c

Error message

Windows script file name {filename:?} contains unsupported characters

What it means

When generating a Windows .cmd launcher for an http tool, the script's own file name is embedded unquoted into the batch body (`"%~dp0{filename}"` line and the launcher file name `{filename}.cmd`). To keep both well-formed and injection-safe, the file name must be non-empty ASCII alphanumeric plus `.`, `_`, `-`; anything else is rejected.

Source

Thrown at src/backend/http.rs:1007

    ensure_plain_bin_name("windows_script_interpreter", interpreter)?;
    if interpreter.is_empty()
        || !interpreter
            .chars()
            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '.' | '_' | '-'))
    {
        eyre::bail!("windows_script_interpreter: {interpreter:?} must be a plain executable name");
    }
    let filename = script
        .file_name()
        .and_then(|filename| filename.to_str())
        .ok_or_else(|| eyre::eyre!("Windows script launcher requires a UTF-8 file name"))?;
    ensure_plain_bin_name("windows script", filename)?;
    if filename.is_empty()
        || !filename
            .chars()
            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '.' | '_' | '-'))
    {
        eyre::bail!("Windows script file name {filename:?} contains unsupported characters");
    }
    let launcher = script.with_file_name(format!("{filename}.cmd"));
    let body = format!("@echo off\r\n{interpreter} \"%~dp0{filename}\" %*\r\n");
    Ok((launcher, body))
}

#[cfg(windows)]
fn write_windows_script_launcher(script: &Path, interpreter: &str) -> Result<()> {
    let (launcher, body) = windows_script_launcher(script, interpreter)?;
    file::write(launcher, body)
}

/// Returns install-time-only option keys for HTTP backend.
pub(crate) fn install_time_option_keys() -> Vec<String> {
    vec![
        "url".into(),
        "checksum".into(),
        "version_list_url".into(),

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Change/rename the URL so the script's base name is simple ASCII (host a copy like `tool.py`)
  2. Download the script yourself into a custom tool layout with a safe name instead of the http backend's launcher path
  3. Avoid file names with spaces or non-ASCII characters for scripts installed via mise on Windows

Example fix

# before
[tools]
"http://example.com/My Great Script.py" = "latest"
# after
[tools]
"http://example.com/my-great-script.py" = "latest"
Defensive patterns

Strategy: validation

Validate before calling

# gate the script file name before adding the tool (ASCII simple name only)
[[ "$(basename "$url")" =~ ^[A-Za-z0-9._-]+$ ]] || echo 'rename the script file'

Prevention

When it happens

Trigger: Installing an http: tool on Windows whose URL ends in a script file name containing spaces, unicode, or special characters (e.g. `my tool-v2.py`, `café.sh`, `tool$(x).js`), when a windows_script_interpreter is configured.

Common situations: Downloading scripts from URLs with human-friendly names ('My Tool.ps1'); URLs with percent-encoded unicode decoded to non-ASCII names; mirrored/hosted scripts renamed casually.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/6058f4dbf7687f81. Report an issue: GitHub.