_module.args not accessible in realised darwinConfiguration?

I’m not using home-manager as a module (this is a deliberate choice because I want users to be able to independently handle their HM configs without admin-rights), so I have no access to osConfig.

However, I propagate unstable via a system-level overlay like so:

{ inputs, pkgs, unstable, ... }:

{
    nixpkgs.overlays = [
       (import ...)
    ];

    # this *adds* unstable to the available args for all modules
    _module.args.unstable = import inputs.nixpkgs-unstable { inherit (pkgs) system config; };

    nix.nixPath = [ "nixpkgs=${pkgs.path}" "unstable=${unstable.path}" ];
}

and then in my flake:

    homeConfigurations = (
      import ./home/hm-builder.nix {
        inherit (nixpkgs) lib;
        inherit inputs;
        systemConfigs = inputs.self.nixosConfigurations // inputs.self.darwinConfigurations;
      }
    ).getHMConfigs; # all top level user names (dirs) under ./home will be used and paired with hostnames if the user is defined in the host definition

where getHMConfigs calls mkHome (for defined user/host combinations):

  mkHome = username: hostname: (
    let
      inherit (systemConfigs."${hostname}") pkgs config;
      inherit (systemConfigs."${hostname}"._module.args) unstable;
      inherit (pkgs) system;
      osConfig = config;
      homeDirectory = "${if lib.hasInfix "darwin" system then "/Users" else "/home"}/${username}";
      configHome = "${homeDirectory}/.config";
    in
    inputs.home-manager.lib.homeManagerConfiguration {
      inherit pkgs;
      modules = [
        ../home/home.nix
        (if builtins.pathExists (./. + "/${username}/overlays") then (./. + "/${username}/overlays") else {})
      ];
      extraSpecialArgs = { inherit inputs username unstable hostname homeDirectory osConfig; };
    });

and finally (just for context) home.nix:

{ pkgs
, unstable
, username
, homeDirectory /* ? pkgs.config.homeDirectory */
, hostname
, lib ? pkgs.lib
, ... }:

{
  imports = [
    ./switch.nix # put the switch script (to apply this flake for system and HM config) in the user's ${HOME}/.local/bin
    (./. + "/${username}/${hostname}") # much simplified: just enforce that the user@host has indeed a defined default.nix in place
  ];

  home.sessionPath = [ "${homeDirectory}/bin" ]; # add to PATH
  fonts.fontconfig.enable = true;
  home.username = username;
  home.homeDirectory = homeDirectory;
  home.stateVersion = "22.11";
}

This works perfectly fine on linux, but on darwin I get

error: attribute '_module' missing

       at /nix/store/f8fwzhc3ibdy04c9a2xfx0dh3h1lp6ia-source/home/hm-builder.nix:12:16:

           11|       inherit (systemConfigs."${hostname}") pkgs config;
           12|       inherit (systemConfigs."${hostname}"._module.args) unstable;
             |                ^
           13|       inherit (pkgs) system;

So the question is, how can I pass the osConfig’s _module attribute from the darwinConfigurations.${myhostname} in the same way as is automatically done for nixosConfigurations?

1 Like

Some relevant conversations (as I’m dealing with a similar issue):

I’m not sure if I understand you completely, but I think I’m doing something similar by using an overlay at the flake level (to give the unstable attribute) and using specialArgs = inputs; (instead of _module.args) to pass in the extra config.

1 Like

Ah, yes, I guess (since I had already de-facto accepted to just pass parts of inputs selectively, I might as well just entirely “embrace” it…)

Come to think of it, if one distinguishes like this:

  • use passed inputs to get certain “extra” functionalities (modules/packages) into the config
  • use overlays to replace packages with customized ones (necessary for fixes to dependencies)

that could be an understanding to reduce overlays which could be considered “legacy” in certain flake scenarios.

If I understood the above links correctly, it is a peculiarity of nixosDarwin that _module.args doesn’t work, but only specialArgs, which as I understand I have to define while calling lib.*Configuration, which shouldn’t be a problem for referring to “fixed” things like unstable or even inputs.

I took a better look at my config, and realised that I already was passing inputs, in order to allow using modules from outside nixpkgs.

So I could re-instantiate unstable by importing from the inputs in the homeManagerConfiguration { extraSpecialArgs = ... } part, but the main question remains: why can’t I get the _module attribute from the realised darwinConfigurations."${hostname}" as I can on nixos and what would be the alternative? (In the repl I also don’t see the specialArgs attribute in the realised darwin system config.)

EDIT: ok, it’s actually a (seemingly arbitrary?) limitation of nix-darwin, that is easy to solve