Do flakes also set the system channel?

Does the channel / commit / branch set in a flake also apply to commands such as nix-shell or nix-env? If not how do I set it?

Also, when I set nixpkgs.url to github:nixos/nixpkgs/nixpkgs-22.05-darwin, will rebuilding automatically fetch the latest commit of that branch and will commands like nix-shell automatically use the latest commit or the one that the system was built from when rebuild was last executed?

1 Like

No, not by default. The “system channel” is in fact just what nixpkgs is set to in NIX_PATH, so we need to set up nix.config.nixPath so that the nixpkgs entry points to the version of nixpkgs provided by our flake. @NobbZ has the most correct implementation of this I’ve seen:

This avoids some pitfalls with using store paths in the nix path, and also sets up the flake registry so nix shell nixpkgs#foo does what you think it does. I honestly think this should be set by default, but we’re not there yet.

It will make any invocation of <nixpkgs> point to the nixpkgs maintained by the flake, which is what most old nix commands use. You can then remove any channels you used with nix-channel (and sudo nix-channel), and all nix commands will still function.

You should probably also use the new commands where possible, though :slight_smile:


I have to admit, that when removing all of roots channels, the handy command-not-found feature will stop to work and throw you an ugly error on an unknown command.

For that to work, roots nixos channel has to stay and kept roughly up to date and that channel has to follow a nixos-* branch that the command-not-found can find its database.

There is an option that would allow you to specify a different location for that DB, though I do not know how to get or build one, as the used DB is different from nix-index.

1 Like

Huh, interesting. I’ve not been paying attention to those suggestions, so never noticed.

I think I’m still partial to removing the root channel, simply because it prevents the usual issues of accidentally installing things from channels you’re not expecting, as well as the issue of forgetting to update something you don’t regularly use. Especially so if it will actually have an effect on the running system.

I wonder what it would take to file out edge cases like this and clean up the workflow of making a full system depend on flake inputs upstream. I guess it will be a bit painful for as long as we have both flakes and channels, since the tools that continue to use channels will probably continue to see development that doesn’t test the edge case of what happens if there isn’t a root channel…

I guess for the moment the suggestion should be to switch to nix-index, or turn off the fancy suggestions altogether?

I know that nix-index maintains their own version of the command-not-found script, that would be compatible with their DB, though I have never been able to get that working.

command-not-found is easily fixed.
Add the channel as input

inputs.nixos-channel.url = "";

get the DB out in an overlay

programs_sqlite = runCommandLocal "programs_sqlite" { } ''
  cp ${inputs.nixos-channel}/programs.sqlite $out

change dbPath

programs.command-not-found.dbPath = pkgs.programs_sqlite;

Thanks for this, this helps at least with keeping the DB in a window with my actually used channel.

But is there a way to make sure I use the exact DB for my commit?


All available versions are listed here Channels for NixOS project(s)

Command locations are not changing that often so it is fine to use a slight more out of up to date one.

Is it also possible to extract the channel url from the channel that serves as the flake input?

I do not think flakes really know or care about channels, they just track a branch in a Git repository. And the fact that some branches are updated when channel advances is not really expressible in Git.

But if the flake is set to follow the release-branch, then it should be possible to use sth. like

inputs.nixos-channel.url = ""

(modulo the build number) where the commit-id-part is determined from the lockfile…

Lack of command-not-found behavior has bugged me ever since I deleted my channels, so I made a rather more involved solution which always gets the programs.sqlite associated with the exact commit your input is set to. See the commit to my personal config repo here:

Assuming you follow a ref which corresponds to a channel, I think this should always work, though integrating it into your own config will take some adjustment.


  • my.lib.mkShellScript is a minor convenience wrapper around pkgs.resholve.writeScript. In this case, all it really does is add the interpreter attribute.
  • inputSpecs is calculated from (import (self + "/flake.nix")).inputs with a bit of code that translates url forms to attrset forms. See nixos-config/inputSpecs.nix at 4856caf264a9b8a62e1ca9e5c430f627835b739a · tejing1/nixos-config · GitHub
  • hred is not packaged in nixpkgs yet (A shame. It’s the best html/xml data extractor around), but node2nix handles it with no tweaks. Or you could use xq from pkgs.yq to accomplish the same task.

do a PR :slight_smile:

that only works if you’re on nixos-unstable or release and do not have any custom commits on top of it.

do a PR :slight_smile:

I probably should. I didn’t at first because I wasn’t familiar enough with nixpkgs’ node stuff, but I could figure it out.

that only works if you’re on nixos-unstable or release and do not have any custom commits on top of it.

Yeah, like I said, “Assuming you follow a ref which corresponds to a channel, I think this should always work.” If that assumption doesn’t hold, you either need to determine a “nearby” commit by whatever means is appropriate for how you consume nixpkgs and adapt this system to that, or you need to generate programs.sqlite yourself.

Hosted by Flying Circus.