Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite recursion when using namespace in home configuration #142

Open
Bear-03 opened this issue Nov 29, 2024 · 6 comments · May be fixed by #147
Open

Infinite recursion when using namespace in home configuration #142

Bear-03 opened this issue Nov 29, 2024 · 6 comments · May be fixed by #147

Comments

@Bear-03
Copy link

Bear-03 commented Nov 29, 2024

Hello.

I am trying to build a simple flake with snowfall, but when I try to use a namespaced module in my home configuration, I get the following error:

building the system configuration...
error:
       … while calling the 'head' builtin
         at /nix/store/4r8s42c9mwfvgdlxv0izb1cmlzrsb5nz-source/lib/attrsets.nix:1574:11:
         1573|         || pred here (elemAt values 1) (head values) then
         1574|           head values
             |           ^
         1575|         else

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

       … while evaluating the option `system.build.toplevel':

       … while evaluating definitions from `/nix/store/4r8s42c9mwfvgdlxv0izb1cmlzrsb5nz-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `assertions':

       … while evaluating definitions from `/nix/store/q1ss75nhmjiydyqw8lbzwbx7cqk8z0qq-source/nixos/common.nix':

       … while evaluating the module argument `namespace' in "/nix/store/9bwi858z3pzcgf9g40bwqvr52lz2zycd-s6wc8mk3jb8ja70aawm5s0ndmda1cyvh-source/homes/x86_64-linux/bear@nixos-laptop/default.nix":

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

       error: infinite recursion encountered
       at /nix/store/4r8s42c9mwfvgdlxv0izb1cmlzrsb5nz-source/lib/modules.nix:515:28:
          514|         addErrorContext (context name)
          515|           (args.${name} or config._module.args.${name})
             |                            ^
          516|       ) (functionArgs f);

I am fairly surprised this is happening since the flake is as small as it can get. Just a module, a home configuration file and a system configuration file; here's their contents:

# modules/home/foo/default.nix
{ namespace, lib, ... }:
with lib;
{
    options."${namespace}".foo = {
        enable = mkEnableOption "Foo";
    };
}
# homes/x86_64-linux/bear@nixos-laptop
{ pkgs, lib, namespace, ... }:
{
    "${namespace}".foo.enable = true;
    home.stateVersion = "24.05";
}
# systems/x86_64-linux/nixos-laptop
{ config, namespace, lib, pkgs, ... }:
{
    imports = [./hardware.nix];

    users.users."bear" = {
        isNormalUser = true;
    };

    system.stateVersion = "24.05";
}
# flake.nix
{
    description = "DataMarket's NixOS flake";

    inputs = {
        # Nix Packages
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

        # Snowfall
        snowfall-lib = {
            url = "github:snowfallorg/lib";
            inputs.nixpkgs.follows = "nixpkgs";
        };

        # Home Manager
        home-manager = {
            url = "github:nix-community/home-manager/release-24.05";
            inputs.nixpkgs.follows = "nixpkgs";
        };
    };

    outputs = inputs: inputs.snowfall-lib.mkFlake {
        inherit inputs;
        src = ./.;

        channels-config = {
            allowUnfree = true;
        };
    };
};

If i change "${namespace}" to a hardcoded internal in the line the module is enabled, it works.

Thanks in advance.

@jakehamilton
Copy link
Member

Ah I think this is an issue with using home-manager as a NixOS module. I checked and it looks like that path is the only one that does not pass down namespace. It absolutely should, this is a bug. We pass namespace to everything else, I am pretty sure that I missed this one instance.

https://github.com/snowfallorg/lib/blob/main/snowfall-lib/home/default.nix#L276

More clearly stated: when using home-manager as a NixOS module, home-manager needs to have namespace passed as a specialArg, but Snowfall Lib is not doing that.

@Bear-03
Copy link
Author

Bear-03 commented Nov 29, 2024

Ah I see, thanks. Is this planned to be resolved? For now I can just hardcore the namespace, but I'd like to do it the correct way.

@jakehamilton
Copy link
Member

It should be fixed in a future release, just depends on me or someone else having the time and energy to implement the change.

@dtgagnon
Copy link
Contributor

@Bear-03

I noticed a few things that don't quite align with @jakehamilton's suspicion, nor the infinite recursion related error. Perhaps there's more at play here then I'm understanding. That said, here's what I noticed:

  1. You have this module option declared in the /modules/home/ directory, but you are attempting to enable it in /systems//nixos-laptop/default.nix. In my experience, there appears to be a strong separation between the home modules and the nixos system modules. For example, you declare home modules only in the user homes/<architecture>/<user>@<host>/default.nix file and nixos modules only in the system systems/<architecture>/<host>/default.nix file. I'm pretty sure you'll get an error if you attempt to activate a module across those boundaries, as you appear to have done in your examples. I'm assuming you don't have a modules/nixos/foo/default.nix as well as a modules/home/foo/default.nix file.
# modules/**home/**foo/default.nix
{ namespace, lib, ... }:
 with lib;
 {
     options."${namespace}".foo = {
         enable = mkEnableOption "Foo";
     };
 }
  1. I may be ignorant, but I believe this is a typo on the architecture.
# homes/**x64_86-linux**/bear@nixos-laptop **---> The architecture is `x86_64-linux`, is it not?**
 { pkgs, lib, namespace, ... }:
 {
     "${namespace}".foo.enable = true;
     home.stateVersion = "24.05";
 }
# systems/**x64_84-linux**/nixos-laptop  **---> Same architecture typo.**
{ config, namespace, lib, pkgs, ... }:
 {
     imports = [./hardware.nix];
 
     users.users."bear" = {
         isNormalUser = true;
     };
 
     system.stateVersion = "24.05";
 }
  1. You're not declaring a specific namespace in your flake. I guess ${namespace} doesn't pass the namespace when it's defaulting to internal? If you declared any namespace here, as shown below, you should be fine using ${namespace} in your configuration modules.
# flake.nix
{
    description = "DataMarket's NixOS flake";

    inputs = {
        # Nix Packages
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

        # Snowfall
        snowfall-lib = {
            url = "github:snowfallorg/lib";
            inputs.nixpkgs.follows = "nixpkgs";
        };

        # Home Manager
        home-manager = {
            url = "github:nix-community/home-manager/release-24.05";
            inputs.nixpkgs.follows = "nixpkgs";
        };
    };

    outputs = inputs: inputs.snowfall-lib.mkFlake {
        inherit inputs;
        src = ./.;

        **snowfall.namespace = "<some-namespace>"; -----> You're missing a line like this, so the default is being used, which is `internal`, per the documentation. This is why things work when you switch to `internal` in your config.**

        channels-config = {
            allowUnfree = true;
        };
    };
};

@Bear-03
Copy link
Author

Bear-03 commented Jan 24, 2025

  1. I am not sure what you mean. I am enabling them in homes/x64_86-linux/bear@nixos-laptop, as the comment in the snippet says.

  2. My bad, that was indeed a typo I made when writing the issue body. However, in the minimal working example that I tested, that error is not present. I will edit the body so this is clear.

  3. I have tried this both with an explicit namespace and the implicit internal namespace and neither of them have worked. Even if that was the case, i don't think it would make sense for "internal" to work any different between nixos and home modules.

@dtgagnon
Copy link
Contributor

dtgagnon commented Jan 24, 2025

  1. Yeah my bad, I misread, from what I see you have that correct.

  2. I agree that it should work the same for both, and there's apparently a pull request waiting for review and merging that fixes that. On another note, I have gotten the declared namespace to work in both nixos and home modules, but the only thing that I have that's different is both a mkLib and mkFlake part to my output, and the mkLib output declares the custom namespace. Not sure that's intended, cause it's a bit confusing, but this is what works for me.

outputs =
    inputs:
    let
      lib = inputs.snowfall-lib.mkLib {
        inherit inputs;
        src = ./.;
        snowfall = {
          meta = {
            name = "";
            title = "";
          };
          namespace = "";
        };
      };
    in

    lib.mkFlake
      {
        inherit inputs;
        src = ./.;

        channels-config = {
          allowUnfree = true;
          permittedInsecurePackages = [ ];
        };

        ...etc...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants