24.05: Add flake to NIX_PATH

From the release notes:

On flake-based NixOS configurations using nixpkgs.lib.nixosSystem, NixOS will automatically set NIX_PATH and the system-wide flake registry (/etc/nix/registry.json) to point and the unqualified flake path nixpkgs to the version of nixpkgs used to build the system.

This makes nix run nixpkgs#hello and nix-build ‘’ -A hello work out of the box with no added configuration, reusing dependencies already on the system.

I use flake based NixOS, and disabled nix channels, and for me it does not work:

$ nix-build '<nixpkgs>' -A hello
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)

       at «none»:0: (source not available)

$ nix-shell -p hello
       … <borked>

         at «none»:0: (source not available)

       … while calling the 'import' builtin

         at «string»:1:18:

            1| {...}@args: with import <nixpkgs> args; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (hello) ]; } ""
             |                  ^

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)

       at «none»:0: (source not available)

what should I check to debug this?

What is the content of NIX_PATH environment variable?

Do you perhaps set nix.nixPath NixOS option? The new module only sets the default NIX_PATH.

I have the same problem:

$ echo $NIX_PATH

$ nix-build '<nixpkgs>' -A hello
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)

       at «none»:0: (source not available)

$ nix-info -m                                                                      
 - system: `"x86_64-linux"`
 - host os: `Linux 6.6.32, NixOS, 24.11 (Vicuña), 24.11.20240528.4a3fc4c`
 - multi-user?: `no`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.2`
 - nixpkgs: `not found`

Hmm, that’s weird. The NIX_PATH value means the nixpkgs-flake.nix works as expected, as far as I can tell.

The following works just fine for me:

$ NIX_PATH=nixpkgs=flake:nixpkgs nix-build '<nixpkgs>' -A hello

The only thing that comes to mind is if you removed nixpgks from the Flake registry but that should give a different error:

$ NIX_PATH=nixpkgs=flake:nonexistent nix-build '<nixpkgs>' -A hello
error: cannot find flake 'flake:nonexistent' in the flake registries

Did you configure Nix registry somehow? What is in your /etc/nix/registry.json and ~/.config/nix/registry.json?

What does nix-instantiate --eval --expr '<nixpkgs>' print?

Don’t set nix.channel.enable to false.

First of all, I had to ensure the doom-emacs env file was deleted/recreated, because it contained the old NIX_PATH.
After deletion of this file, the value of NIX_PATH is nixpkgs=flake:nixpkgs
But it did not work

While trying this, I saw @zendo suggestion, and removed my nix.channel.enable setting. Now it works.

I did not expect Nix channel to be required for this, I am not using Nix channels.

$ cat /etc/nix/registry.json

$ cat ~/.config/nix/registry.json
cat: /home/azuwis/.config/nix/registry.json: No such file or directory

$ nix-instantiate --eval --expr '<nixpkgs>'
       … while calling the 'findFile' builtin

         at «string»:1:1:

            1| <nixpkgs>
             | ^

       error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)

       at «none»:0: (source not available)

Yes, I have nix.channel.enable = false;, removing this make nix-build works.

I think this will solve the problem

# modules/system/default.nix (snippet directly from my config)

	nix = {
		channel.enable = false;
		settings.nix-path = ["nixpkgs=${pkgs.path}"]; # -> For making nix-shell available while disabling channels.
		settings.experimental-features = [ "nix-command" "flakes" ];

Add settings.nix-path = ["nixpkgs=${pkgs.path}"];

Hmm, that sounds like a bug to me.

It is caused by this line:

Apparently the nix-path configuration option takes precedence over the environment variable (even when not using pure evaluation).

nix.settings.nix-path = ["nixpkgs=${pkgs.path}"];

Turns out the issues with emptying the nix-path config were already heavily discussed in the PR that introduced it. There is also a PR that reverts the emptying with more conversation. Unfortunately, because some programs (e.g. nix-shell --pure) unset NIX_PATH and Nix falls back to channel paths when the variable is unset, reverting would make the nix.channel.enable = false ineffectual in those situations.

Thanks for the information.

How about set:

nix.settings.nix-path = ["nixpkgs=${pkgs.path}"];

as @beginnernixosenjoyer sugguested, and leave NIX_PATH empty?

Since nixpkgs.flake.setNixPath is enabled by default on any flake-based system, that would clobber NIX_PATH environment variable for everyone using flakes (until the Nix bug is fixed).

Though maybe we could have it set nix.settings.nix-path when nix.channel.enable = false and nix.nixPath otherwise. That would make the clobbering opt-in just like it is now.

nix.channel.enable = false;
nix.settings.nix-path = "nixpkgs=flake:nixpkgs";

Works for me.

As the Nix bug says, the config takes precedence over NIX_PATH environment variable, which breaks various tools that rely on setting it. You can easily reproduce it with NIX_PATH=foo=$HOME nix-instantiate '<foo>' --eval --expr