{"record":{"id":"8d0f0180f52787ce","repo":"jdx/mise","slug":"invalid-version","errorCode":null,"errorMessage":"invalid version: {}","messagePattern":"invalid version: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/latest.rs","lineNumber":59,"sourceCode":"}\n\nimpl Latest {\n    pub async fn run(self) -> Result<()> {\n        let before_date = self.get_before_date()?;\n        let config = Config::get().await?;\n        let Self {\n            tool,\n            asdf_version,\n            installed,\n            minimum_release_age: _,\n        } = self;\n        let prefix = match &tool.tvr {\n            None => asdf_version,\n            Some(ToolRequest::Version { version, .. }) => Some(version.clone()),\n            // `sub-N:<base>` resolves its base against the backend, so it is handled\n            // below once the backend (and its plugin) is ready.\n            Some(ToolRequest::Sub { .. }) => None,\n            _ => bail!(\"invalid version: {}\", tool.style()),\n        };\n\n        let mut backend = tool.ba.backend()?;\n        let mpr = MultiProgressReport::get();\n        if let Some(plugin) = backend.plugin() {\n            plugin.ensure_installed(&config, &mpr, false, false).await?;\n            backend = tool.ba.backend()?;\n        }\n        let prefix = match &tool.tvr {\n            Some(ToolRequest::Sub {\n                sub, orig_version, ..\n            }) => Some(\n                resolve_sub_base(&config, &backend, sub, orig_version, before_date, false).await?,\n            ),\n            _ => match prefix {\n                Some(v) => Some(config.resolve_alias(&backend, &v).await?),\n                None => None,\n            },","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/cli/latest.rs#L41-L77","documentation":"`mise latest TOOL@VERSION` only accepts request forms it can turn into a prefix: a concrete version (node@20.1.0 or prefix digits like node@20), a `sub-N:<base>` channel, or no version at all. Other ToolRequest variants — `path:` requests, `system`, and prefix patterns like `20.x` — hit the catch-all arm and are rejected as 'invalid version' before any backend lookup.","triggerScenarios":"`mise latest node@path:/usr/local` , `mise latest node@system`, or `mise latest node@20.x`; also `mise latest node@ref:main` since Ref is not an accepted variant here.","commonSituations":"Piping a tool version string from config (which allows path:/system/ref forms) straight into `mise latest`; muscle memory from `mise use` syntax applied to `latest`.","solutions":["Use a plain version or prefix: `mise latest node` or `mise latest node@20`","For sub-channels use the supported form: `mise latest node@sub-1:22`","Do not forward `path:`/`system`/`ref:`/`N.x` specifiers from other config into `mise latest` — filter them out in your script first"],"exampleFix":"# before\nmise latest node@path:~/.local/node\n# after\nmise latest node@20","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\nreq=$1\ncase \"$req\" in\n  *:path:*|path:*|system|ref:*|*.x|*.X) echo \"unsupported request form for mise latest: $req\" >&2; exit 2 ;;\nesac\nmise latest \"$req\"","typeGuard":null,"tryCatchPattern":"mise latest \"$tool@$ver\" 2>err.log || { grep -q 'invalid version' err.log && echo \"pass a plain version or prefix, e.g. $tool@20\" >&2; exit 2; }","preventionTips":["Only forward bare versions or numeric prefixes into mise latest","Sanitize config-sourced version strings (path:/system/ref:/N.x) before reuse on the CLI"],"tags":["cli","latest","version-specifier","mise"],"backgroundTag":"unsupported-version-specifier","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}