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
- Wrap colon-containing versions in a recognized prefix - 'prefix:' keeps everything after the first colon: 'mise use tool@prefix:2024.01.15T10:30'
- Use the supported prefixes as intended: ref:, tag:, branch:, rev:, prefix:, path:/abs/path, sub-<name>:
- Strip colons from generated version strings before passing them to mise
- 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
- Sanitize generated version strings (strip colons) in build scripts
- Use prefix: when a version legitimately contains colons
- Reserve colons for the documented prefixes; never docker-style name:tag
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
- {plugin_name} is not a valid plugin name
- --connect-timeout must be greater than zero
- config file not found: {}
- config file not found: {}
- invalid version: {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/4847e6e57a01cffb.
Report an issue: GitHub.