jdx/mise · error

invalid version

Error message

invalid version: {}

What it means

This error is thrown by the `mise latest` command when the tool request is not a plain version, prefix-less request, or `sub-N:<base>` request — i.e. the version spec cannot be reduced to a registry-version prefix. Only concrete versions and supported prefix forms are meaningful for 'latest' lookup; other request kinds (e.g. path or ref requests) are rejected.

Solutions

  1. Pass a plain version or prefix instead, e.g. mise latest node@22 or mise latest node@22.1
  2. For refs or paths, use the appropriate command (mise install / mise use) rather than mise latest
  3. Check the spec with mise ls-remote <tool> to see supported version forms

Example fix

// before
mise latest node@ref:main
// after
mise latest node@22
Defensive patterns

Strategy: validation

Validate before calling

SPEC="$1"
case "$SPEC" in
  *ref:*|*path:*|*sub-*) echo "mise latest needs a plain version/prefix, not '$SPEC'" >&2; exit 1 ;;
  *) ;;
esac

Prevention

When it happens

Trigger: Running `mise latest` with a tool argument that parses to an unsupported ToolRequest variant, such as a ref:... request, a path-based spec, or other non-version syntax.

Common situations: Passing `ref:main` or a git/path spec to `mise latest` expecting it to resolve a latest version; copy-pasting a complex version spec from .tool-versions that latest doesn't support.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/cli/latest.rs:71

}

impl Latest {
    pub(crate) async fn run(self) -> Result<()> {
        let before_date = self.get_before_date()?;
        let config = Config::get().await?;
        let Self {
            tool,
            asdf_version,
            installed,
            minimum_release_age: _,
        } = self;
        let prefix = match &tool.tvr {
            None => asdf_version,
            Some(ToolRequest::Version { version, .. }) => Some(version.clone()),
            // `sub-N:<base>` resolves its base against the backend, so it is handled
            // below once the backend (and its plugin) is ready.
            Some(ToolRequest::Sub { .. }) => None,
            _ => bail!("invalid version: {}", tool.style()),
        };

        let ba = prefix
            .as_deref()
            .and_then(|prefix| tool.ba.with_registry_version(prefix));
        let ba = ba.as_ref().unwrap_or(&tool.ba);
        let mut backend = ba.backend()?;
        let mpr = MultiProgressReport::get();
        if let Some(plugin) = backend.plugin() {
            plugin.ensure_installed(&config, &mpr, false, false).await?;
            backend = ba.backend()?;
        }
        let prefix = match &tool.tvr {
            Some(ToolRequest::Sub {
                sub, orig_version, ..
            }) => Some(
                resolve_sub_base(&config, &backend, sub, orig_version, before_date, false).await?,
            ),

View on GitHub (pinned to 533346cc37)