{"record":{"id":"c0f3fef09a202472","repo":"jdx/mise","slug":"expose-requires-uv-or-newer-but-uv-is-installed","errorCode":null,"errorMessage":"{} expose requires uv@{} or newer, but uv@{} is installed","messagePattern":"(.+?) expose requires uv@(.+?) or newer, but uv@(.+?) is installed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/pipx.rs","lineNumber":1153,"sourceCode":"        &self,\n        ctx: &InstallContext,\n        options: &PipxOptions<'_>,\n    ) -> Result<()> {\n        if options.expose()?.is_empty() {\n            return Ok(());\n        }\n        let Some(version) =\n            crate::backend::semver_version_from_toolsets_or_path(self, &ctx.config, &ctx.ts, \"uv\")\n                .await\n        else {\n            bail!(\n                \"{} expose requires uv@{} or newer, but the installed uv version could not be determined\",\n                self.ba.short,\n                UV_WITH_EXECUTABLES_FROM_VERSION\n            );\n        };\n        if semver_is_older_than(&version, UV_WITH_EXECUTABLES_FROM_VERSION).unwrap_or(false) {\n            bail!(\n                \"{} expose requires uv@{} or newer, but uv@{} is installed\",\n                self.ba.short,\n                UV_WITH_EXECUTABLES_FROM_VERSION,\n                version\n            );\n        }\n        Ok(())\n    }\n}\n\nenum PipxRequest {\n    /// git+https://github.com/psf/black.git@24.2.0\n    /// psf/black@24.2.0\n    Git(String),\n    /// black@24.2.0\n    Pypi(String),\n}\n","sourceCodeStart":1135,"sourceCodeEnd":1171,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/backend/pipx.rs#L1135-L1171","documentation":"ensure_uv_supports_expose enforces a minimum uv version of 0.8.5 (UV_WITH_EXECUTABLES_FROM_VERSION) for the `expose` option. If the resolved uv version is older than that, install bails with the installed version named in the message.","triggerScenarios":"Installing a pipx tool with expose options while the uv resolved from the toolset or PATH is semantically older than 0.8.5 (semver_is_older_than returns true).","commonSituations":"Pinned old uv in mise.toml (e.g. uv = \"0.7.0\"); stale uv on PATH predating the feature; team lockfile locking an old uv version.","solutions":["Upgrade uv to >= 0.8.5: `mise use uv@latest` or bump the pinned version","Update mise.lock via `mise lock` after upgrading so the newer uv is replayed","Remove the expose option if you must stay on an older uv"],"exampleFix":"// before\n[tools]\nuv = \"0.7.12\"\n\"pipx:ruff\" = { version = \"latest\", expose = [\"ruff\"] }\n// after\n[tools]\nuv = \"latest\"\n\"pipx:ruff\" = { version = \"latest\", expose = [\"ruff\"] }","handlingStrategy":"validation","validationCode":"const { stdout } = await $`uv --version`;\nconst v = stdout.match(/uv (\\d+)\\.(\\d+)\\.(\\d+)/).slice(1).map(Number);\nif (v[0] < 1 && (v[0] * 1e6 + v[1] * 1e3 + v[2]) < (0 * 1e6 + 8 * 1e3 + 5))\n  throw new Error(\"expose requires uv >= 0.8.5\");","typeGuard":null,"tryCatchPattern":"try { await $`mise install pipx:ruff` } catch (e) {\n  if (/or newer/.test(e.message) && /uv@/.test(e.message)) { await $`mise use uv@latest`; await $`mise install pipx:ruff`; }\n  else throw e;\n}","preventionTips":["Pin uv = \"latest\" or at least >= 0.8.5 wherever expose is used","Keep uv in mise.lock current; run periodic `mise upgrade uv`","Note the 0.8.5 minimum in team docs for expose users"],"tags":["pipx","uv","version-constraint","expose"],"backgroundTag":"version-out-of-range","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}