jdx/mise · error · std::io::Error

(failed to join PATH segments; wrapped as std::io::Error…

Error message

{err} (failed to join PATH segments; wrapped as std::io::Error with kind InvalidInput)

What it means

In `position_shims_before_path`, mise rebuilds the PATH (with shims directories removed/repositioned) using `std::env::join_paths`. If any segment contains the platform path separator character (e.g. a directory whose name contains `:` on Unix), `join_paths` fails with `JoinPathsError`, which mise wraps as an `std::io::Error` of kind `InvalidInput` and surfaces with this message.

Solutions

  1. Find the offending PATH entry (`echo $PATH | tr ':' '\n'`) and rename the directory or remove it from PATH.
  2. Fix the shell profile/export that introduced the separator-containing entry.
  3. Temporarily unset/repair PATH and re-run `mise activate`.

Example fix

// before
export PATH="$PATH:/opt/my:weird/dir"

// after
export PATH="$PATH:/opt/my-weird-dir"
Defensive patterns

Strategy: validation

Validate before calling

echo "$PATH" | tr ':' '\n' | grep -n ':' || echo "PATH entries clean"

Prevention

When it happens

Trigger: Calling `activate` when the inherited `PATH` contains an entry with an embedded path-separator character, causing `std::env::join_paths` in `position_shims_before_path` to return `Err`.

Common situations: A directory literally named with a colon (`my:dir`) added to PATH; a broken shell profile exporting PATH entries containing `:`; artifacts of sloppy env manipulation by another tool.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/cli/activate.rs:306

    }
    flags
}

fn position_shims_before_path() -> std::io::Result<Option<ActivatePrelude>> {
    let user_shims = dirs::shims();
    let system_shims = dirs::system_shims();
    let mut path = vec![user_shims];
    if system_shims.is_dir() && !file::storage_paths_eq(&path[0], &system_shims) {
        path.push(system_shims);
    }
    path.extend(
        env::PATH
            .iter()
            .filter(|path| !file::is_mise_shims_dir(path))
            .cloned(),
    );
    let path = std::env::join_paths(path)
        .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err))?;
    Ok(Some(ActivatePrelude::Set(
        PATH_KEY.to_string(),
        path.to_string_lossy().to_string(),
    )))
}

fn remove_shims_from_path() -> std::io::Result<Option<ActivatePrelude>> {
    if !env::PATH.iter().any(|path| file::is_mise_shims_dir(path)) {
        return Ok(None);
    }
    let path = std::env::join_paths(
        env::PATH
            .iter()
            .filter(|path| !file::is_mise_shims_dir(path)),
    )
    .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err))?;
    Ok(Some(ActivatePrelude::Set(
        PATH_KEY.to_string(),

View on GitHub (pinned to 533346cc37)