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
- Drop the version field and let the flake's locked revision determine the version.
- Pin a specific commit by embedding the revision in the flake URL: `github:NixOS/nixpkgs/<rev>#ripgrep`.
- Manage that package with a different backend that supports version pins if exact versions are required.
- 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
- Never set version fields on nix:-managed packages
- Encode versions as flake URL revisions (github:owner/repo/<rev>#pkg)
- Use flake.lock / your own flake for version control
- If exact versions are required, choose a backend with supports_version_pins() == true
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
- does not support declarative package removal
- flatpak cannot upgrade a pinned version
- invalid Nix package attribute
- mas cannot install a pinned version
- pacman cannot install a pinned version
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)