stylix icon indicating copy to clipboard operation
stylix copied to clipboard

bug: `attribute 'lib' missing` when attempting to use stylix

Open pyrox0 opened this issue 2 years ago • 25 comments

I'm using stylix in a nix config, and whenever I try to evaluate my system configuration, it errors out.

The error is:

       error: attribute 'lib' missing

       at /nix/store/lbgfhradyynfljgmv9bywhg9h3p25qyf-modules/chromium/nixos.nix:5:5:

            4|   options.stylix.targets.chromium.enable =
            5|     config.lib.stylix.mkEnableTarget "Chromium, Google Chrome and Brave" true;
             |     ^
            6|

I don't know what is causing this problem, but if you can help, that would be much appreciated. Please let me know if there are any other details you need.

pyrox0 avatar Feb 27 '23 14:02 pyrox0

Are you sure you're importing the stylix module ? That may be the problem... I can't tell much more without having an example of a configuration that produces this problem.

dwarfmaster avatar Feb 27 '23 14:02 dwarfmaster

Yes I am. I will push my code changes to my forge and send a link to the relevant files.

pyrox0 avatar Feb 27 '23 14:02 pyrox0

Ok, so

  • The repo is here
  • The relevant flake.nix lines are here. These pull in the stylix module from inputs and import the configuration file for the host
  • The stylix config for the host is imported on line 24 of the configuration.nix file listed above. All options are taken directly from the documentation. I hope this helps, please let me know if there is other relevant documentation I can provide.

The way I build this is with nixos-rebuild switch --use-remote-sudo --flake . --show-trace

pyrox0 avatar Feb 27 '23 14:02 pyrox0

This has been reported before (#20), although it was never clear what caused it.

I would assume something outside of Stylix is the problem? You have a lot of flake inputs, and the latest commit works fine with a minimal config.

If this is the case, perhaps moving our utils into the config.stylix namespace rather than config.lib would avoid interference? Or injecting them into the real lib, if that is possible. However, these would both be breaking changes.

danth avatar Feb 27 '23 15:02 danth

Well, I don't know what exactly the problem would be, but I would be glad to test any potential changes. I may fork and try to put everything in a config.stylix namespace and see if that works.

pyrox0 avatar Feb 27 '23 15:02 pyrox0

Maybe it's due to the fact that config is not computed yet when the options are evaluated (it should be fully lazy and work, but I admit not liking depending on things in config for the structure of options).

dwarfmaster avatar Feb 27 '23 18:02 dwarfmaster

So, I ran into a similar problem and I've got some debugging information that may help.

The error I received was:

       error: attribute 'xserver' missing

       at /nix/store/23gl8kb384mgqm0ys6bvcbhdpknfjlrm-modules/gnome/nixos.nix:16:17:

           15|       default = config.stylix.autoEnable
           16|              && config.services.xserver.desktopManager.gnome.enable;
             |                 ^
           17|     };

Now, if I--before I even load stylix--set stylix.autoEnable = false I no longer get the error. So I removed the disabling of autoEnable and started digging a bit. Dropping into the debugger at that point showed me that the nixos modules had yet to load and populate config with their settings/defaults. There were only other pieces of my config in there. I don't have GNOME enabled (nor xserver) so they weren't populated by my config either.

The default of the option for the GNOME theming feels suspect. I don't have any specifics or extensive experience writing nixModules to back that statement up, but using config in the options hash might be tempting the recursive gods to smite you. :stuck_out_tongue_closed_eyes:

If I'm not mistaken, that default needs to evaluate as the module loads which is why the autoEnable = false short-circuited the check. If the GNOME / xserver bits load first or the user sets those values themselves, then there's no problem because it has a value to read (either constant false or the user's preference) rather than an evaluated default.

In an effort to prove this out, I walked stylix back to ba324393e9414f57a2d0ba5a1edee5cd02b8af18 and reevaluated the flake. I ended up with this error:

       error: attribute 'mkEnableTarget' missing

       at /nix/store/prq3jjd62gxlb87nlnppnjc9rxmi8rxy-modules/gnome/nixos.nix:7:5:

            6|   options.stylix.targets.gnome.enable =
            7|     config.lib.stylix.mkEnableTarget "GNOME" config.services.xserver.desktopManager.gnome.enable;
             |     ^
            8|

Different, yes, but still in the GNOME module. I went one further step and walked it back to ce781e1d963311216b2837e014f522c3620f0639.

The evaluation succeeded.

My bone-headed suggestion would be to set a default of true/false everywhere and use lib.mkIf around the actual changes to evaluate later in the cycle to avoid the issue. Something like: lib.mkIf (cfg.autoEnable || cfg.gnome.enable) and see if that doesn't fix the issue. I'm going to fork stylix shortly to try it out for myself and see if it works.

jboyens avatar Jun 24 '23 14:06 jboyens

Nope. The fork idea didn't work. I do not understand the magic. Hopefully meaning can be found in the above...

jboyens avatar Jun 24 '23 15:06 jboyens

Couldn't leave it alone. This seems to be work great:

  options.stylix.targets.gnome.enable =
    lib.mkOption {
      description = lib.mdDoc "Whether to style GNOME";
      type = lib.types.bool;
      default = config.stylix.autoEnable 
             && (config.services.xserver.desktopManager.gnome.enable or false);
    };

Gleaned from here: https://nixos.org/manual/nix/unstable/language/operators.html#attribute-selection

jboyens avatar Jun 24 '23 15:06 jboyens

Is this still an issue?

danth avatar Apr 03 '24 20:04 danth

Sort of, new problems have arisen that hit before this problem so I'm not 100% sure if it's gone.

The defaults in a lot of places are breaking because recursion is trying to use the default before the definition the default is based upon exists.

The latest instance I get (w/ commit 4da2d793e586f3f45a54fb9755ee9bf39d3cd52e) is:


       error: attribute 'programs' missing

       at /nix/store/hqjk2q12m84v1aqyr9df7i34w99rraag-modules/nixvim/nixvim.nix:17:50:

           16|   config = lib.mkIf ((config.programs ? nixvim) && config.stylix.targets.nixvim.enable) (
           17|     lib.optionalAttrs (builtins.hasAttr "nixvim" options.programs) {

This problem can be worked around by shimming in a module prior to stylix that just defines an empty options.programs = {} which is enough to make the defaults get passed so that loading can continue. It will eventually evaluate correctly so the fix just tries to break an implicit load-order dependency.

Why commit 4da2d793e586f3f45a54fb9755ee9bf39d3cd52e you ask? Well, the commit AFTER that creates a separate problem:

       error: attribute 'mkEnableTarget' missing

       at /nix/store/pwivl3092cg504g6m06y3mns0h5343v2-modules/nixos-icons/nixos.nix:7:5:

            6|   options.stylix.targets.nixos-icons.enable =
            7|     config.lib.stylix.mkEnableTarget "the NixOS logo" true;
             |     ^
            8|

This one doesn't have a simple work around.

jboyens avatar Apr 03 '24 21:04 jboyens

@jboyens I'm also running into the same issue with mkEnableTarget missing. From my testing, modules that set config.nixpkgs.overlays are causing the breakage. These are the nixos-icons and gnome modules.

heraldofsolace avatar Jun 05 '24 18:06 heraldofsolace