Evan Relf

NixOS: Fix `command-not-found` Database File Error

If you try to run a command but don't have the program installed, it isn't always easy to figure out which package you need to install.

command-not-found is a helpful utility provided by NixOS that suggests packages from Nixpkgs that provide the program you wanted to run:

$ cowsay "Hello, world!"
The program 'cowsay' is not in your PATH. It is provided by several packages.
You can make it available in an ephemeral shell by typing one of the following:
  nix-shell -p cowsay
  nix-shell -p neo-cowsay
$ nix-shell -p cowsay
[nix-shell:~]$ cowsay "Hello, world!"
 _______________
< Hello, world! >
 ---------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Hopefully repeating the example above on your machine gives you similarly friendly output, but on some machines you may see this scary-looking error:

$ cowsay "Hello, world!"
DBI connect('dbname=/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite','',...) failed: unable to open database file at /run/current-system/sw/bin/command-not-found line 13.
cannot open database `/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite' at /run/current-system/sw/bin/command-not-found line 13.

If you read the error message closely, you'll see that command-not-found tried to open a SQLite database located at /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite, but it didn't exist.

This happens when the root user is missing the nixos channel. You can fix this by adding a channel and naming it nixos:

$ sudo nix-channel --add https://nixos.org/channels/nixos-21.11 nixos
$ sudo nix-channel --update nixos

It's important that you use a nixos-* channel (e.g. nixos-21.11, nixos-unstable, etc.), because the other channels (e.g. nixpkgs-21.11, nixpkgs-unstable, etc.) don't include the programs.sqlite database file.

Alternatively, if you'd rather eschew channels and the NIX_PATH entirely like I do, you can configure command-not-found to look for programs.sqlite elsewhere:

# Put this in your NixOS configuration
{
  programs.command-not-found.dbPath = "<your-absolute-path-here>";
}