jdx/mise · error

: ' ' must be a plain file name (no path separators or…

Error message

{option}: '{name}' must be a plain file name (no path separators or parent directories)

What it means

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.

Solutions

  1. Change the bin/rename_exe value to just the file name and configure any subdirectory separately via the path option that supports relative paths
  2. 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
  3. Verify no template expansion is injecting slashes into the name

Example fix

# before
[bin]
rename_exe = "bin/mytool"
# after
[bin]
rename_exe = "mytool"
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn assert_plain_name(opt: &str, name: &str) -> Result<(), String> {
    if name.is_empty() || name.contains('/') || name.contains('\\') || name.contains("..") {
        return Err(format!("{opt}: {name:?} must be a plain file name"));
    }
    Ok(())
}

Type guard

fn is_plain_file_name(name: &str) -> bool {
    !name.is_empty() && !name.contains('/') && !name.contains('\\') && !name.contains("..")
}

Prevention

When it happens

Trigger: 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.

Common situations: Tool authors copying a repo-relative path into the bin field, absolute paths pasted from local machines, or Windows-style paths with backslashes.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/20394c91fcc3ecc5. Report an issue: GitHub.

Appendix: source

Thrown at src/backend/static_helpers.rs:1198

        p.file_name()
            .map(|n| {
                let name = n.to_string_lossy();
                !should_skip_file(&name, true) && glob.matches(&name)
            })
            .unwrap_or(false)
    }) {
        return Ok(Some(available.remove(idx)));
    }

    Ok(None)
}

/// Rejects `bin`/`rename_exe` names that are not plain file names (`../tool`,
/// `/abs/tool`, `bin/tool`), which would otherwise be joined onto the install
/// or search directory and place the binary outside it.
pub(crate) fn ensure_plain_bin_name(option: &str, name: &str) -> eyre::Result<()> {
    if !file::is_plain_file_name(name) {
        bail!(
            "{option}: '{name}' must be a plain file name \
             (no path separators or parent directories)"
        );
    }
    Ok(())
}

/// Rejects a configured binary path that is absolute or contains parent
/// components, while preserving the established `bin = "bin/tool"` form.
pub(crate) fn ensure_safe_relative_bin_path(option: &str, path: &str) -> eyre::Result<()> {
    if !file::is_safe_relative_path(path) {
        bail!(
            "{option}: '{path}' must be a safe relative path \
             (no absolute paths or parent directories)"
        );
    }
    Ok(())
}

View on GitHub (pinned to 533346cc37)