jdx/mise · error

has a uv dependency graph; use uv with a PyPI package to…

Error message

{} has a uv dependency graph; use uv with a PyPI package to replay it

What it means

validate_lock_options refuses a plain-pipx operation when the tool's lock entry contains a uv dependency graph (uv_lock_allowed returns false). The graph was produced by uv against a PyPI package and can only be replayed with uv; proceeding with pipx would ignore the recorded dependencies.

Solutions

  1. Install/enable uv (`mise use uv@latest`, keep uvx enabled) so the graph can be replayed with uv
  2. Run `mise lock` after switching backends to regenerate the lock without the uv graph
  3. Delete the stale lock entry for the tool and reinstall if you intentionally want pipx-only resolution
Defensive patterns

Strategy: validation

Validate before calling

if (lockEntry.hasUvGraph && !(await isInstalled("uv")))
  throw new Error("lock has a uv graph; install uv or regenerate the lock");

Try / catch

try { await $`mise install pipx:ruff` } catch (e) {
  if (/use uv with a PyPI package/.test(e.message)) { await $`mise use uv@latest`; await $`mise install pipx:ruff`; }
  else throw e;
}

Prevention

When it happens

Trigger: Installing or resolving a pipx tool whose lock entry has a uv dependency graph while the current operation is not uv/PyPI-based (e.g. pipx fallback install because uv is missing or uvx disabled), from prepare_install_version, resolve_uv_lock, or validate_uv_lock.

Common situations: uv was upgraded away or uvx disabled after locking, so install falls back to pipx; running on a machine without uv while the repo's mise.lock carries a uv-built graph.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/backend/pipx/lock.rs:68

    pub(super) fn uv_lock_options_supported(&self, tv: &ToolVersion) -> bool {
        let raw = tv.request.options();
        let opts = PipxOptions::new(&raw);
        [opts.uvx_args(), opts.pipx_args()]
            .into_iter()
            .flatten()
            .all(|s| s.trim().is_empty())
    }

    pub(super) fn validate_lock_options(&self, tv: &ToolVersion) -> Result<()> {
        if !self.uv_lock_options_supported(tv) {
            bail!(
                "{} dependency locking does not support uvx_args or pipx_args",
                self.ba.short
            );
        }
        if !self.uv_lock_allowed(tv) {
            bail!(
                "{} has a uv dependency graph; use uv with a PyPI package to replay it",
                self.ba.short
            );
        }
        Ok(())
    }

    async fn lock_uv_program(&self, config: &Arc<Config>) -> Result<PathBuf> {
        let uv = self.spawnable_dependency(config, None, "uv").await
            .ok_or_else(|| eyre!("Python dependency locks require uv >= {MIN_UV_VERSION}; install it with `mise use uv`"))?;
        let output = CmdLineRunner::new(&uv).arg("--version").read().await?;
        let version = output
            .split_whitespace()
            .nth(1)
            .ok_or_else(|| eyre!("cannot determine uv version"))?;
        if semver_is_older_than(version, MIN_UV_VERSION).unwrap_or(true) {
            bail!("Python dependency locks require uv >= {MIN_UV_VERSION}");
        }

View on GitHub (pinned to 533346cc37)