Nix-shell: two machines, different results

I manage my mac using nix, nix-darwin & flakes GitHub - ahmedelgabri/dotfiles: ~ 🍭 ~ I use this on multiple machines.

Today after updating flakes, I’m getting different outputs per machine when I try to run nix-shell on some projects.

Machine one (MBP 15" 2015) (complains about csview)

Machine two (MBP 16" 2019) (complains about nodejs-16_x)

Both machines have the same nix version, built using the same flakes.lock file, not sure what is wrong here or how can I debug this?

if I do darwin-rebuild --rollback everything works fine. Updating breaks only on a single machine.

It broke after this update (nix: update flakes & deprecated options · ahmedelgabri/dotfiles@8b6cc25 · GitHub) but not sure why one machine would be different than the other?

import <nixpkgs>

Will use the whatever the nixpkgs channel on a given machine is set to; are both machines at the same channel / version?

1 Like

Since this is using flakes, I’m setting the channels using nix.nixPath so they should both have the same channel.

Please check that this is actually the case. Setting nixPath will only take effect after running nix-darwin rebuild (as for NixOS), and only when you re-initialize your shell.

It won’t work if you upgrade your system from an older configuration when changing both nixPath and your mkShell.

@fricklerhandwerk I already ran darwin-rebuild switch --flake . & restarted my machine too.

Okay weird. Just as a sanity-check, what if you replaced <nixpkgs> by the same nixpkgs commit hash on both machines?

nix.dev strongly discourages using search paths due to the kind of problem you experience.

The first machine has a warning about /nix/var/nix/profiles/per-user/root/channels but not the other. Something must be different between your two machines. A channel is different or something.

1 Like

Does nix-shell use flakes? How would nix-shell know to map <nixpkgs> to what is in the system config flake?

You might get more diagnostics with nix-shell --pure.

I think you are going to find that nix-shell is pulling in whatever channel info is set for each user (and machine).

Consider replacing/wrapping shell.nix with a flake.nix and using nix develop. Although, this still won’t be connected to the system config nixpkgs; flakes are meant to be isolated from system and environment dependencies.

@Solene

Regarding this, I tried everything and couldn’t get rid of it, there is even an issue from 2019 Nix programs keep saying `warning: Nix search path entry ...` · Issue #2982 · NixOS/nix · GitHub but thanks that was a pointer to solving the problem.

@ericgundrum nix-shell --pure didn’t really give any more information other than the screenshots.

Anyway, I solved the issue & yes it was a channels issue. One machine had

nixpkgs https://nixos.org/channels/nixpkgs-unstable

and the other had

darwin https://github.com/LnL7/nix-darwin/archive/master.tar.gz
nixpkgs https://nixos.org/channels/nixpkgs-unstable

So I added darwin also and ran nix-channel --update and both are working as expected. I guess the main issue here was my lack of understanding that channels are not managed by flakes. I thought they were so I assumed that both machines should behave the same even inside shell.nix but that was not correct.

So what does nix.nixPath do then, because I’m confused? :thinking:

1 Like

It sets the NIX_PATH variable, which should have the effect you’re expecting. I’d guess that it isn’t present in whatever shell you’re running nix-shell in, for some reason, e.g. because you’re not sourcing the global bash profile, or something along those lines.

As a friendly tip, I’d recommend removing the imperatively set channels entirely. Then you only have your declarative config, and if that isn’t working, you get an obvious error rather than this confusion.

1 Like

To avoid the session problem, I created “proxy” links in /etc managed by systemd-tempfiled.

I could have used etc.* as well, though well I wanted to leant tempfile.d :smiley:

I’m pretty sure there has to be something in nix-darwin with an equivalent effect.

@TLATER $NIX_PATH is properly set on both machines

$ echo $NIX_PATH
/Users/ahmed/.nix-defexpr/channels:darwin-config=/Users/ahmed/.nixpkgs/darwin-configuration.nix:nixpkgs=/nix/store/n27fp8jik7263crzs6y6hdc1k76x2mvk-source:darwin=/nix/store/i7rxw4bp4z16796haadc40ahrs88ivlk-source:home-manager=/nix/store/gby2davr5n2hsxf1rfl6gaf8i17m71ff-source:/nix/var/nix/profiles/per-user/root/channels
$ echo $NIX_PATH
/Users/ahmedelgabri/.nix-defexpr/channels:darwin-config=/Users/ahmedelgabri/.nixpkgs/darwin-configuration.nix:nixpkgs=/nix/store/n27fp8jik7263crzs6y6hdc1k76x2mvk-source:darwin=/nix/store/i7rxw4bp4z16796haadc40ahrs88ivlk-source:home-manager=/nix/store/gby2davr5n2hsxf1rfl6gaf8i17m71ff-source:/nix/var/nix/profiles/per-user/root/channels

So I will remove the channels and try again tomorrow and see.

With flakes you should use nix develop.

1 Like

With flakes there might be “legacy” reasons to do “legacy” stuff.

Just because you “should”, it doesn’t neccessarily mean you can.

3 Likes

@TLATER removing the channels works, thanks.

I agree, but the issues here seem to be channel related.

Even if in the end you must use nix-shell for legacy reasons, it could be useful to verify whether nix develop works to narrow down the problem.

It is not always as trivial as wrapping the shell.nix in a flake.

Debugging “legacy” by making it non-legacy anymore is often not trivial, not paid work and there are quicker ways to debug the problem.

Whenever “diamond paths” appear, the first thing to check is the NIX_PATH and especially to also check the “unnamed” entries, which resolve through their content.

Personally I got back control. I manage my nix.nixPath through the system configuration and all of its entries point to well controlled locations. All entries are “named”.

That is the proper fix to avoid interference through nix-channel.

1 Like

@ParetoOptimalDev adding to what @NobbZ mentioned about legacy & how it’s not always trivial to change, this is an article that reflects the same sentiment by someone who tried to move from shell.nix to flakes and how it was not as simple How to Learn Nix, Part 47: New and unimproved shells

1 Like

Huh, so I take it that means imperative channels take priority? Good to know, I’d never tried this before. Another little gotcha to add to my grab-bag of “help, I somehow unreproducibilized nix” gotchas :stuck_out_tongue:

I’m guessing this is because /nix/var/nix/profiles/per-user/root/channels is added to the end of the variable. Maybe this could be changed to prevent problems like this in the future?

1 Like

Not sure what you mean by “priority”.

-I has highest priority. First match (left to right) wins.
Then NIX_PATH will be considered. Again, first match (left to right) wins.

The problem here, and were stuff gets out of control, are unnamed entries.

For each folder in the unnamed nix path entry, a named entry is implicitly created.

And nix-channel works exactly by placing symlinks in some well known unnamed entries of the default nix path.

This is why they sometimes appear to have a higher priority.

As for some reason people still prefer to append to any variable that carries PATH in its name… Despite this doesn’t make any sense ever…

2 Likes