jdx/mise · error

Nix cannot install package version pin

Error message

Nix cannot install package version pin '{pkg}'; pin the flake source revision instead

What it means

Nix installs whatever revision the flake reference resolves to; there is no `pkg@version` concept in flake attribute paths, so the Nix manager declares `supports_version_pins() == false` and `reject_pins` pre-checks every request before install/upgrade. If any request carries a version, mise fails fast with guidance to encode the version as a pinned flake source revision instead of silently ignoring it.

Solutions

  1. Drop the version field and let the flake's locked revision determine the version.
  2. Pin a specific commit by embedding the revision in the flake URL: `github:NixOS/nixpkgs/<rev>#ripgrep`.
  3. Manage that package with a different backend that supports version pins if exact versions are required.
  4. Use a flake.lock or your own flake to control versions declaratively.

Example fix

// before
{"name": "nixpkgs#ripgrep", "version": "14.1.0"}

// after
{"name": "github:NixOS/nixpkgs/9b5328b7f76a91aef6c0f1e5c1d0f2f1b0c1f8ab#ripgrep"}
Defensive patterns

Strategy: validation

Validate before calling

// strip versions before handing requests to the nix manager
let filtered: Vec<_> = requests.into_iter()
    .map(|mut r| { debug_assert!(r.version.is_none(), "nix ignores versions"); r.version = None; r })
    .collect();

Try / catch

match manager.install(&pkgs, &opts).await {
    Err(e) if e.to_string().contains("version pin") => {
        eprintln!("re-run without version, or pin the flake revision in the name");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A package entry resolves to the Nix manager with a version set — e.g. `packages = [{ name = "nixpkgs#ripgrep", version = "14.1.0" }]` or a tool-versions-style pin — and `install`/`upgrade` calls `reject_pins`.

Common situations: Users copying version-pin syntax from apt/npm/pip workflows into Nix-managed packages; shared mise.toml where the same package is version-pinned for other managers; tool files carrying versions that get mapped onto the nix backend.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/system/packages/nix.rs:270

    let status = tokio::process::Command::new("nix")
        .args(&args)
        .stdin(Stdio::null())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()
        .await?;
    if !status.success() {
        bail!(
            "nix {} failed; see Nix's diagnostic above. Ensure nix-command and flakes are enabled and the profile uses modern `nix profile` format",
            shell_words::join(&args)
        );
    }
    Ok(())
}

fn reject_pins(pkgs: &[PackageRequest]) -> Result<()> {
    if let Some(pkg) = pkgs.iter().find(|p| p.version.is_some()) {
        bail!(
            "Nix cannot install package version pin '{pkg}'; pin the flake source revision instead"
        );
    }
    Ok(())
}

#[async_trait(?Send)]
impl SystemPackageManager for NixManager {
    fn name(&self) -> &str {
        "nix"
    }

    fn is_available(&self) -> bool {
        cfg!(unix) && crate::file::which("nix").is_some()
    }

    fn unavailable_reason(&self) -> String {
        if cfg!(unix) {

View on GitHub (pinned to 533346cc37)