jdx/mise · error

invalid prefix: {}

Error message

invalid prefix: {}

What it means

Thrown by the FromStr impl of ToolVersionType (src/cli/args/tool_arg.rs:71) when the version half of a tool spec contains ':' and the segment before the first colon is not a recognized prefix - only ref, tag, branch, rev, prefix, path, and sub-<name> are allowed. Any other text before a colon is rejected as an 'invalid prefix'.

Source

Thrown at src/cli/args/tool_arg.rs:71

    }
}

impl FromStr for ToolVersionType {
    type Err = eyre::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        trace!("parsing ToolVersionType from: {}", s);
        Ok(match s.split_once(':') {
            Some((ref_type @ ("ref" | "tag" | "branch" | "rev"), r)) => {
                Self::Ref(ref_type.to_string(), r.to_string())
            }
            Some(("prefix", p)) => Self::Prefix(p.to_string()),
            Some(("path", p)) => Self::Path(PathBuf::from(p)),
            Some((p, v)) if p.starts_with("sub-") => Self::Sub {
                sub: p.split_once('-').unwrap().1.to_string(),
                orig_version: v.to_string(),
            },
            Some((p, _)) => bail!("invalid prefix: {}", style::ered(p)),
            None if s == "system" => Self::System,
            None => Self::Version(s.to_string()),
        })
    }
}

impl Display for ToolVersionType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Path(p) => write!(f, "path:{}", p.to_string_lossy()),
            Self::Prefix(p) => write!(f, "prefix:{p}"),
            Self::Ref(rt, r) => write!(f, "{rt}:{r}"),
            Self::Sub { sub, orig_version } => write!(f, "sub-{sub}:{orig_version}"),
            Self::System => write!(f, "system"),
            Self::Version(v) => write!(f, "{v}"),
        }
    }
}

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Wrap colon-containing versions in a recognized prefix - 'prefix:' keeps everything after the first colon: 'mise use tool@prefix:2024.01.15T10:30'
  2. Use the supported prefixes as intended: ref:, tag:, branch:, rev:, prefix:, path:/abs/path, sub-<name>:
  3. Strip colons from generated version strings before passing them to mise
  4. Double-check sub-tool syntax: it must be 'sub-<name>:<version>'

Example fix

# before
mise use mytool@2024.01.15T10:30
# Error: invalid prefix: 2024.01.15T10

# after
mise use mytool@prefix:2024.01.15T10:30
Defensive patterns

Strategy: type-guard

Validate before calling

# bash: reject version specs with an unrecognized prefix before calling mise
is_valid_version() {
  case "$1" in
    ref:*|tag:*|branch:*|rev:*|prefix:*|path:*|sub-*:*) return 0 ;;
    system) return 0 ;;
    *:*) return 1 ;;
    *) return 0 ;;
  esac
}
is_valid_version "$VER" || { echo "invalid version spec: $VER" >&2; exit 1; }

Type guard

// Rust guard mirroring ToolVersionType::from_str acceptance
fn is_valid_version_spec(s: &str) -> bool {
    match s.split_once(':') {
        Some((p, _)) => {
            matches!(p, "ref" | "tag" | "branch" | "rev" | "prefix" | "path") || p.starts_with("sub-")
        }
        None => true,
    }
}

Prevention

When it happens

Trigger: 'mise use tool@2024.01.15T10:30' (timestamp containing colons), 'mise use tool@channel:stable' (channel is not a prefix), 'subpython:3.12' instead of 'sub-python:3.12', or argument-order mixups that drop a path/URL into the version position.

Common situations: Version strings pasted from release notes or build stamps that contain ISO timestamps; users expecting docker-style 'name:tag' syntax; scripts interpolating $TIME or git refs into versions.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/4847e6e57a01cffb. Report an issue: GitHub.