Why does my system derivation include derivations it doesn't depend on?

I’m trying to get the pname and version for every package installed on my system, which `nix derivation show /run/current-system` seems to be the best available tool for. But when looking at the data I noticed that my system had multiple of the same package at the same version installed, and some of them aren’t even existent in the Nix store/show as not being a dependency in `nix why-depends`? Can anyone who’s more experienced with Nix than me explain what’s causing this?

To cut off the most obvious things, I do have extra flake inputs but they all are pinned to my standard nixpkgs. I’ve also completely garbage collected, including old generations, and restarted my computer before running these commands. My base branch is nixos-unstable and I’m running Nix 2.34.3.

Coreutils isn’t the only package I’ve seen this with (also libx11, xz), but it does seem generally linked to being a dependency as I haven’t yet seen it happen with a leaf package.

nix derivation show /run/current-system --recursive | jq -r ‘[.derivations[] | select(.env.version!=null and .env.pname==“coreutils”) | “\(.env.pname) \(.env.version) \(.env.out)”]’

[
“coreutils 9.10 /nix/store/57an1npwig5vqzf7yqi4ilxsqc9730rk-coreutils-9.10”,
“coreutils 9.10 /nix/store/k9g4qjxn1jrgz5jnbxkpd1a8m8kx4gvs-coreutils-9.10”,
“coreutils 9.10 /nix/store/pslch3nk0mbgj8f8wf78cpd7inqvd90a-coreutils-9.10”,
“coreutils 9.10 /nix/store/74sind1d6vf2bfwd7yklg8chsvzqxmmq-coreutils-9.10”
]

The first one in the list works and shows what I would expect it to, but not the second one:

nix why-depends /run/current-system /nix/store/k9g4qjxn1jrgz5jnbxkpd1a8m8kx4gvs-coreutils-9.10

this path will be fetched (642.3 KiB download, 1.9 MiB unpacked):

/nix/store/k9g4qjxn1jrgz5jnbxkpd1a8m8kx4gvs-coreutils-9.10

‘/nix/store/wwfx5x6pzvmpak118crx246ysvp4s2pq-nixos-system-i7-8700k-26.05.20260324.46db2e0’ does not depend on '/nix/store/k9g4qjxn1jrgz5jnbxkpd1a8m8kx4gvs-coreutils-9.10’

The cache does show that as a valid derivation that it has, so my best guess is that maybe I’m using `nix why-depends` wrong? But still, my understanding is that Nixpkgs tries to avoid having packages use any version of a library except the most recent, so I don’t understand how a package would have the same version but multiple different derivations within a single system.

What am I missing?

1 Like

Other order. The system you last booted is a gcroot while you’re still booted off of it, so you don’t lose e.g. kernel modules. Might make a difference.

You might be using why-depends wrong. Those packages could be dependencies of packages that need to override something to get particular functionality or something. Same exact commit of the source code, but different compile conditions.

Overall, my advice is generally to not worry about what’s in your nix store. What ends up in there isn’t always obvious, and that’s fine. It’s an internal aspect for the most part. If you’re running out of space, it’s something to consider, but even then, focus on what’s in the closure of things you keep rooted, not what paths happen to be in the store.

2 Likes

Just tried gcing and rebooting again, still there, so I don’t think this is it.

Override dependencies could be it, I didn’t think about those, but I would still expect why-depends to show them. Maybe one of my flake imports is doing that?

I understand and agree with this for basically all normal use-cases, but I need this information for a project I’m working on :slight_smile:

nix derivation show --recursive asks for all of the build dependencies of the argument. nix why-depends only cares about the dependencies of the argument as a store path — things in its closure, in other words. The latter is a subset of the former.

So in your case, things that build things that build things that build… your current system involve more copies of coreutils than your system actually uses.

Btw, the nix derivation show command is following build-time dependencies, but the why-depends command is querying runtime dependencies. you can use the --derivation flag with nix why-depends to get build-time dependencies.

Are you sure these paths still actually exist in the filesystem post-gc? If they’re build-only dependencies, they shouldn’t.

That was it, thanks both of you. While I’m here, is there any equivalent to nix derivation show for runtime dependencies, like what nix why-depends looks for by default?

I’m not sure of a way to do it with the new cli, but nix-store --query --references (or nix-store --query --requisites for the closure) will list them.

EDIT: Ah, nix path-info can do it:

nix path-info --json /nix/store/hash-name | jq '.[].references[]' -r
1 Like