How do you inspect NixOS / Home Manager configurations?

When I want to debug my modules I often want to check that I have an option set to what I think it is set to.

Here are my notes on how I currently do this:


NixOS options are under .#nixosConfigurations.<config>.config. So for example:

# Show security.pam.loginLimits option
nix eval .#nixosConfigurations.chungito.config.security.pam.loginLimits

For NixOS hosts, Home Manager options are under
.#nixosConfigurations.<config>.config.home-manager.users.<user> So for example:

# Show programs.waybar.enable option
nix eval .#nixosConfigurations.chungito.config.home-manager.users.brendan.programs.waybar.enable

For hosts using Home Manager standalone, they are under
.#homeConfigurations.<config>. So for example:

nix eval '.#homeConfigurations.jackmanb@jackmanb01.config.wayland.windowManager.sway.xwayland'

This is fine for small/scalar options but doesn’t really work for inspecting larger attrsets as it just prints one big single-line Nix expression. Passing --json and then piping to jq sometimes helps but:

  1. Some values can’t be serialised as JSON at all (e.g. functions)
  2. Some values are intended to produce an error when serialised.

I think the Nix REPL would offer a way to work around this issue but it doesn’t actually seem to be usable (e.g. I can’t find a way to go through command history? Am I missing something there?)

Home Manager has an instantiate/option commands but they don’t work on Flake configurations.

So… is there a good solution here?

I use the repl, personally.

nix-repl> f = builtins.getFlake "git+file:${(builtins.getEnv "PWD")}"
nix-repl> f.nixosConfigurations.chungito.config.security.pam.loginLimits
…

With Lix’s repl-overlays feature, I can have f automatically defined when I enter the repl.

2 Likes

nixos-rebuild repl can do this just fine as well

❯ nixos-rebuild repl -f ~/src/mine/nixnix -A lamorna.system
building Nix...
Nix 2.28.5
Type :? for help.
Loading installable 'lamorna.system'...
Added 6 variables.
nix-repl> 

Season to taste with flakes or whatever.

The repl’s :p command can handle errors gracefully by printing an error for the problematic thunk and continuing:

nix-repl> :p { foo = builtins.abort "foo"; bar = 1; }
{
  bar = 1;
  foo = «error: evaluation aborted with the following error message: 'foo'»;
}

I find it’s most valuable to put together a repl environment with my config’s module args available in scope, then exploring config (or trying snippets of code to see if they do what I think they do).

I wonder if there’s a way to print the whole configuration at once.

Yeah, this is also something I’d wondered. You can’t evaluate the whole config, since there are options etc that fail the program if you evaluate them (like the ones I mentioned breaking --json).

It would be cool if you could print the subset of the configuration that actually got evaluated when you realise your config. I have no idea if this is possible.

To the REPL users… am I missing anything or does it not support command history?

1 Like

Lix’s does. Idk about CppNix’s.

Not with an unpatched Nix, but it’s not hard to extend Nix to support this. I demoed this here: Comparing module system configurations - #8 by rhendric

It definitely does for me, both within and across REPL sessions. I don’t know why it isn’t working for you.

1 Like

I think you would be interested in nix-inspect.

1 Like

No idea about standalone hm.
But nixos-option works for nixos configs, and it’s already on your system. It handles individual options and nested options too. It would of course work for hm as a nixos module as well.
It even tells you which files affected the final value.

Oh, it works on my other computer, seems just a normal readline prompt. So… yeah I guess I need to debug that.

Seems useful but as you implied, I think it only works for NixOS, so no good for standalone HM. (I use non-NixOS systems too. I suspect this is not a particularly common case. But I have a separate distro for my day job).