bug: `attribute 'lib' missing` when attempting to use stylix
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.
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.
Yes I am. I will push my code changes to my forge and send a link to the relevant files.
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.nixfile 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
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.
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.
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).
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.
Nope. The fork idea didn't work. I do not understand the magic. Hopefully meaning can be found in the above...
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
Is this still an issue?
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 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.