How to explicity pass arguments config and pkgs to home-manager's NixOS module

Newbie here–I’m just polishing up my first NixOS config and came across an irritating hole in my understanding of implicit argument passing.

I’m using home-manager as a NixOS module and my system config is in a flake, the heart of which looks something like:

let pkgs = import nixpkgs {
  inherit system;
  overlays = (import ./overlays);
}
in 
...
{
      myHost = nixpkgs.lib.nixosSystem {
        inherit system;
        modules = [
          ./system/configuration.nix
          home-manager.nixosModules.home-manager {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.myUser = import ./home.nix { inherit pkgs; };
          }
        ];
      };
    }

But when I run sudo nixos-rebuild switch --flake ".#myHost", I get:

error: anonymous function at /nix/store/l9hrn8apr46db57m25hvbwql5ab3vs4f-source/home.nix:1:1
 called without required argument 'config'

Now this is a fairly intelligible error message–I just have to pass config to ./home.nix and it should be all squared away. But where is an appropriate config to use? What gets passed to ./home.nix when I forgo the overlays and instead put home-manager.users.myUser = import ./home.nix?

If anybody has good documentation for the argument passing behavior it’d be greatly appreciated.

Thanks

Make home-manager.users.myUser = import … a home-manager.users.myUser.imports = [ ./home.nix ], then the module system will take over and call with the correct arguments.

4 Likes

Thanks! I had to add nixpkgs.pkgs = pkgs to get nix to respect my overlays but it worked. Much obliged.

I am still curious though: which config is being passed by the module system to home.nix? I tried

home-manager.users.myUser = import ./home.nix {
  inherit pkgs; 
  config = pkgs.config; 
}

which worked, but I don’t want to accidentally stop the propagation of the correct/default config. Would it use the nixpkgs in scope unless specified otherwise by nixpkgs.pkgs?

It would be the final config of the home-manager instance of the module system, not the config attribute from Nixpkgs. You can do sort of η-expansion:

home-manager.users.myUser.imports = [
  ({ config, ... }: import ./home.nix {
    inherit config pkgs;
  })
]

But I would just recommend the solution suggested above, as it will have home-manager to inject the correct config.

If you want to learn how the module system works, I would recommend just reading its source code. See Import list in `configuration.nix` vs `import` function - #5 by jtojnar for where to start.

By the way, you do not need to include the config argument if you do not use it, the ellipsis will just swallow it.

1 Like

Ok, awesome! That makes sense. Thanks for clarifying.
I did use the above solution. It just bugged me that I didn’t know what it was doing.
I’ll read through that. Thanks for the suggestion.