Flake-Parts Overlays Not Working

I can’t get overlays to work in flake-parts and I’m not sure what I am doing wrong. As far as I can tell, I am doing exactly what the flake-parts documentation recommends. I am trying to rewrite my config using flake-parts and I keep getting errors that a package from an overlay is missing.

Here is my flake.nix: dotfiles/flake.nix at dacf76227a146ad5d7ba9283391e6f94e81e0099 · Anomalocaridid/dotfiles · GitHub

Below is my perSystem.

perSystem =
        { pkgs, system, ... }:
        {
          # Apply overlay and allow unfree packages
          _module.args.pkgs = import nixpkgs {
            inherit system;
            overlays = [
              # custom overlay
              (import ./pkgs)
              # Hyprland community tools
              inputs.hyprland-contrib.overlays.default
            ];
            config.allowUnfree = true;
          };

          formatter = pkgs.nixfmt-rfc-style;
        };
    };

Edit: I originally had @azuwis’s solution marked as the solution because it worked fine and seemed to be the best fit for my case. However, it caused issues after I started using the ez-config module. I changed it to @StepBroBD’s solution because it seems to work fine even with ez-config.

Can you share the full error and command you used?

I used sudo nixos-rebuild test to rebuild my config and the error is below.

For context, scratchpad is the name of a package in the hyprland-contrib flake.

Also, just in case it’s relevant, if I use a way other than an overlay to get the package, it’ll just show a similar error for the other overlay I have defined.

error:
       … while calling the 'head' builtin
         at /nix/store/0jr2kk95c34c0b6yxi75q4fqgb43kqkm-source/lib/attrsets.nix:1575:11:
         1574|         || pred here (elemAt values 1) (head values) then
         1575|           head values
             |           ^
         1576|         else

       … while evaluating the attribute 'value'
         at /nix/store/0jr2kk95c34c0b6yxi75q4fqgb43kqkm-source/lib/modules.nix:821:9:
          820|     in warnDeprecation opt //
          821|       { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          822|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: attribute 'scratchpad' missing
       at /nix/store/asz1z1w3kk3silwp2jar0nikgwrn0hwv-source/home/hyprland.nix:125:37:
          124|
          125|       "$scratchpad" = "${lib.getExe pkgs.scratchpad} -m '$menu --dmenu'";
             |                                     ^
          126|

Setting perSystem’s _module.args.pkgs will NOT affect your NixOS system configurations. It only affects the use of pkgs in perSystem blocks.

You’ll need to add a module to your NixOS system config to use consume your custom or external overlays. For example:

flake =
        let
          shared = [
            { nixpkgs.overlays = [
              # custom overlay
              (import ./pkgs)
              # Hyprland community tools
              inputs.hyprland-contrib.overlays.default
            ]; }
            ./modules
            inputs.lix-module.nixosModules.default
        ...
        in
        rec {
          nixosConfigurations.home-pc = nixpkgs.lib.nixosSystem {
            modules = [
              ./hosts/home-pc/configuration.nix
              diskoConfigurations.home-pc
            ] ++ shared;
...

EDIT: use @azuwis ’s or @Aleksana ’s answer

1 Like

You need to consume the pkgs defined by perSystem using withSystem, something like:

nixosConfigurations.home-pc = withSystem "x86_64-linux" ({pkgs, system}:
  nixpkgs.lib.nixosSystem {
    inherit system;
    modules = [
      ./hosts/home-pc/configuration.nix
      diskoConfigurations.home-pc
    ] ++ shared;
    specialArgs = {
      inherit inputs pkgs;
    };
  };
)
2 Likes

Or pkgs = (getSystem system).allModuleArgs.final

2 Likes

quoting flake-parts cheat-sheet

Anything you can do at the top level, you can do in perSystem as well, although you may have to @ match those module arguments.

For example, add change the top level function header to e.g. toplevel@{ config, ... }: /*...*/ so you can access toplevel.config despite plain config being shadowed by perSystem = { config, ... }: /*...*/.

So , why not nixos system?
– noob
https://flake.parts/cheat-sheet

I think @azuwis’s and @Aleksana’s answers are far better than mine, I’m already in the process of re-writing my own config to match their examples:

a:

      flake.nixosConfigurations.a = let system = "x86_64-linux"; in
        nixpkgs.lib.nixosSystem {
          inherit system;
          inherit ((getSystem system).allModuleArgs) pkgs;
          modules = [ ];
        };

b:

      flake.nixosConfigurations.b =
        withSystem "x86_64-linux" ({ pkgs, system, ... }: nixpkgs.lib.nixosSystem {
          inherit pkgs system;
          modules = [ ];
        });
1 Like

I’m a bit unsure what your question is. Do you mean: why don’t we set pkgs in nixosSystem with the pkgs in toplevel.config.<some attr path>?

I traced toplevel.config, and there’re lots of stuff in there. IMO withSystem and getSystem is a easier way to get the pkgs out from toplevel than direct access with attribute path, they all do the same thing

1 Like

perSystem ’s _module.args.pkgs will NOT affect your NixOS system configurations. It only affects the use of pkgs in perSystem blocks.
In order to accessible from another point, a local var in nix need be in lexical scope ( like it’s in case of with e1: e2 , e2 can access it as with makes it available to its lexical scope ), atrrs can be copied ( in a let in {} block}, similarly with rec {} ,
In your own solution ( autopilot ), you put perSystem = {} (is perSystem = :_ isthat some sort of overlay, whereas_module.args` was about accessing modules? idk* ) in outer -files ( iirc) .
In any case , I wasn’t commenting on what should be done, but merely meant that inputs/ (arg for modules) can be passed in multiple ways so long as they can be accessed. May be I should ve consulted the whole context of the thread, before putting a comment .
At this point I d like to emphasise the question *