Help with infinite recursion in a flake

Here is my flake: GitHub - refaelsh/dotfiles at 8a72f4fd458b83d1b4b02cb18d4c1fc20735f65c. I am building my NixOS from it.
Recently, I’ve added this: dotfiles/flake.nix at 8a72f4fd458b83d1b4b02cb18d4c1fc20735f65c · refaelsh/dotfiles · GitHub.
Its a flake I am working on my local hard drive - its supposed to configure Xmobar via home-manager module.
But I am getting this error when rebuilding my system:

error: infinite recursion encountered

Please help :slight_smile:

You don’t need an additional flake input for it, it’s already present in your flake.
You should be able to add (${inputs.self} + /nixmobar) or a relative path ../nixmobar (which is my personal preference) to your imports in your HM config.

Then you can delete the inner flake.nix.

1 Like

I am sorry @waffle8946, but can I please bother you with concrete changes you are suggesting?
I am afraid I did not understand your answer at all.

I think @waffle8946 means something like this:

{
  description = "NixOS flake";

  inputs = {
    # with the short url syntax, you don't need "?ref="
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    ...

    # Delete this
    # nixmobar.url = "./nixmobar";
  };

  outputs = {
    ...
  };
}

and in home-manager/home.nix

{ ... }:
{
  # programs.home-manager.enable = true;
  home.stateVersion = "24.05";
  # home.username = "refaelsh";
  # home.homeDirectory = "/home/refaelsh";

  imports = [
    # Delete this
    #inputs.nixmobar.homeModules.nixmobar

    # Just import it like your other modules
    ../nixmobar # uses default.nix

    ./alacritty.nix
    ./git.nix
    ./fzf.nix
    ./lf.nix
    ./librewolf.nix
    ./kitty.nix
    ./mangohud.nix
    ./nixmobar.nix
    ./starship.nix
    ./termonad.nix
    ./wezterm.nix
    # ./xmobar.nix
    ./zsh.nix
  ];
}

and then delete the flake.nix and flake.lock file in nixmobar/

2 Likes

@railwhale Thats exactly what I did a few days a go while I was developing my module and testing it and etc. Now, I wanna “package” my module as a flake. Thats why I have nixmobar.url = "./nixmobar";, it is intentional.

No, you want to expose the module as a flake output.

Just add a new entry in your top-level flake.nix in the outputs:

nixosModules.nixmobar = ./nixmobar;
1 Like

No, you want to expose the module as a flake output .

Yes, you are correct. New terminology, still learning flakes :slight_smile:

Just add a new entry in your top-level flake.nix in the outputs:

nixosModules.nixmobar = ./nixmobar;

But I wanna use the output of my new flake Nixmobar.
The way you are suggesting, I will not use the output of my new flake Nixmobar.

If you create a new flake output then you can use inputs.self.nixosModules.nixmobar

Or if it’s an HM module then you can name is homeModules/homeManagerModules.nixmobar (there’s no official naming per the schema for HM).

1 Like

Thats exactly what I am currently doing. I have this in Nixmpobar’s flake output:

homeModules.nixmobar = import ./default.nix;

And then, I use it like this in my NixOS flake:

inputs =
{
.
.
.
    nixmobar.url = "./nixmobar";
.
.
.
}
outputs =
{
.
.
.
    modules = [
      inputs.nixmobar.homeModules.nixmobar
   ];
.
.
.
}

But I get the error: infinite recursion encountered error.

That’s not what I wrote, I said keep it in one flake not two separate ones.
And use inputs.self.homeModules.nixmobar not a separate flake input.

Also you still haven’t shared the full error, just saying there’s infrec doesn’t tell us much.
But I suggest following my recommendation first, then check if there’s an error, so that we are not chasing an issue that may not need addressing.

1 Like

That’s not what I wrote, I said keep it in one flake not two separate ones.

Oh! Sorry, I did not understood you. Now I get what you meant. I think. Let me think on it and I get back here asap.

@waffle8946 I did what you are suggesting and now I this error: error: The option home does not exist.
Here are the dotfiles: GitHub - refaelsh/dotfiles at 2bce698c5f28aefa0270fc26d0581d5ddd7fd3d7.
What I did in short is like this (in my NixOS flake):

 outputs =
    { self, nixpkgs, ... }@inputs:
    {
      homeModules.nixmobar = import ./nixmobar/default.nix;

      nixosConfigurations = {
        myNixos = nixpkgs.lib.nixosSystem {
          specialArgs = {
            inherit inputs system;
          };

          modules = [
            ./nixos/configuration.nix

            inputs.home-manager.nixosModules.home-manager
            ./home-manager

            inputs.self.homeModules.nixmobar
          ];
        };
      };
    };

This line needs to go in your HM config, not your nixos config.

1 Like

You are correct. I moved it there, and now I get this error:

building the system configuration...
error:
       … while calling the 'head' builtin

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-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/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-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: infinite recursion encountered

       at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:520:28:

          519|         addErrorContext (context name)
          520|           (args.${name} or config._module.args.${name})
             |                            ^
          521|       ) (functionArgs f);

That indicates that you’re trying to use a module arg that was never passed into the module system.
I’m guessing you didn’t add inputs to extraSpecialArgs as well?
But --show-trace should indicate which arg and the location it’s used.

1 Like

Here is a run with --show-trace:

building the system configuration...
error:
       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1571:24:

         1570|     let f = attrPath:
         1571|       zipAttrsWith (n: values:
             |                        ^
         1572|         let here = attrPath ++ [n]; in

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1205:18:

         1204|         mapAttrs
         1205|           (name: value:
             |                  ^
         1206|             if isAttrs value && cond value

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1208:18:

         1207|             then recurse (path ++ [ name ]) value
         1208|             else f (path ++ [ name ]) value);
             |                  ^
         1209|     in

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:254:72:

          253|           # For definitions that have an associated option
          254|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                                                                        ^
          255|

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

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:836:28:

          835|         # Process mkMerge and mkIf properties.
          836|         defs' = concatMap (m:
             |                            ^
          837|           map (value: { inherit (m) file; inherit value; }) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))

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

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:837:128:

          836|         defs' = concatMap (m:
          837|           map (value: { inherit (m) file; inherit value; }) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
             |                                                                                                                                ^
          838|         ) defs;

       … while calling 'dischargeProperties'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:908:25:

          907|   */
          908|   dischargeProperties = def:
             |                         ^
          909|     if def._type or "" == "merge" then

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1205:18:

         1204|         mapAttrs
         1205|           (name: value:
             |                  ^
         1206|             if isAttrs value && cond value

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1208:18:

         1207|             then recurse (path ++ [ name ]) value
         1208|             else f (path ++ [ name ]) value);
             |                  ^
         1209|     in

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:254:72:

          253|           # For definitions that have an associated option
          254|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                                                                        ^
          255|

       … while evaluating the option `assertions':

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:836:28:

          835|         # Process mkMerge and mkIf properties.
          836|         defs' = concatMap (m:
             |                            ^
          837|           map (value: { inherit (m) file; inherit value; }) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))

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

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:837:128:

          836|         defs' = concatMap (m:
          837|           map (value: { inherit (m) file; inherit value; }) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
             |                                                                                                                                ^
          838|         ) defs;

       … while calling 'dischargeProperties'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:908:25:

          907|   */
          908|   dischargeProperties = def:
             |                         ^
          909|     if def._type or "" == "merge" then

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:914:11:

          913|         if def.condition then
          914|           dischargeProperties def.content
             |           ^
          915|         else

       … while calling 'dischargeProperties'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:908:25:

          907|   */
          908|   dischargeProperties = def:
             |                         ^
          909|     if def._type or "" == "merge" then

       … from call site

         at /nix/store/781lg988vxf6dw57igf4l6plm92dfj6c-source/nixos/common.nix:110:20:

          109|
          110|       assertions = flatten (flip mapAttrsToList cfg.users (user: config:
             |                    ^
          111|         flip map config.assertions (assertion: {

       … while calling 'flatten'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/lists.nix:431:13:

          430|   */
          431|   flatten = x:
             |             ^
          432|     if isList x

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/lists.nix:433:21:

          432|     if isList x
          433|     then concatMap (y: flatten y) x
             |                     ^
          434|     else [x];

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/lists.nix:433:24:

          432|     if isList x
          433|     then concatMap (y: flatten y) x
             |                        ^
          434|     else [x];

       … while calling 'flatten'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/lists.nix:431:13:

          430|   */
          431|   flatten = x:
             |             ^
          432|     if isList x

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1096:10:

         1095|     attrs:
         1096|     map (name: f name attrs.${name}) (attrNames attrs);
             |          ^
         1097|

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1096:16:

         1095|     attrs:
         1096|     map (name: f name attrs.${name}) (attrNames attrs);
             |                ^
         1097|

       … while calling anonymous lambda

         at /nix/store/781lg988vxf6dw57igf4l6plm92dfj6c-source/nixos/common.nix:110:66:

          109|
          110|       assertions = flatten (flip mapAttrsToList cfg.users (user: config:
             |                                                                  ^
          111|         flip map config.assertions (assertion: {

       … from call site

         at /nix/store/781lg988vxf6dw57igf4l6plm92dfj6c-source/nixos/common.nix:111:9:

          110|       assertions = flatten (flip mapAttrsToList cfg.users (user: config:
          111|         flip map config.assertions (assertion: {
             |         ^
          112|           inherit (assertion) assertion;

       … while calling 'flip'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/trivial.nix:317:16:

          316|   */
          317|   flip = f: a: b: f b a;
             |                ^
          318|

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/types.nix:577:22:

          576|       merge = loc: defs:
          577|         mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
             |                      ^
          578|             (mergeDefinitions (loc ++ [name]) elemType defs).optionalValue

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:858:59:

          857|       if isDefined then
          858|         if all (def: type.check def.value) defsFinal then type.merge loc defsFinal
             |                                                           ^
          859|         else let allInvalid = filter (def: ! type.check def.value) defsFinal;

       … while calling 'merge'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/types.nix:881:22:

          880|         check = x: isAttrs x || isFunction x || path.check x;
          881|         merge = loc: defs:
             |                      ^
          882|           (base.extendModules {

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:254:28:

          253|           # For definitions that have an associated option
          254|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                            ^
          255|

       … while calling 'mapAttrsRecursiveCond'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/attrsets.nix:1201:5:

         1200|     f:
         1201|     set:
             |     ^
         1202|     let

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:246:33:

          245|           ({ inherit lib options config specialArgs; } // specialArgs);
          246|         in mergeModules prefix (reverseList collected);
             |                                 ^
          247|

       … while calling 'reverseList'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/lists.nix:1116:17:

         1115|   */
         1116|   reverseList = xs:
             |                 ^
         1117|     let l = length xs; in genList (n: elemAt xs (l - n - 1)) l;

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:241:25:

          240|       merged =
          241|         let collected = collectModules
             |                         ^
          242|           class

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:457:37:

          456|
          457|     in modulesPath: initialModules: args:
             |                                     ^
          458|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:458:7:

          457|     in modulesPath: initialModules: args:
          458|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
             |       ^
          459|

       … while calling 'filterModules'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:425:36:

          424|       # modules recursively. It returns the final list of unique-by-key modules
          425|       filterModules = modulesPath: { disabled, modules }:
             |                                    ^
          426|         let

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:451:31:

          450|           disabledKeys = concatMap ({ file, disabled }: map (moduleKey file) disabled) disabled;
          451|           keyFilter = filter (attrs: ! elem attrs.key disabledKeys);
             |                               ^
          452|         in map (attrs: attrs.module) (genericClosure {

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:412:22:

          411|           let
          412|             module = checkModule (loadModule args parentFile "${parentKey}:anon-${toString n}" x);
             |                      ^
          413|             collectedImports = collectStructuredModules module._file module.key module.imports args;

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:371:11:

          370|         then
          371|           m:
             |           ^
          372|             if m._class != null -> m._class == class

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:412:35:

          411|           let
          412|             module = checkModule (loadModule args parentFile "${parentKey}:anon-${toString n}" x);
             |                                   ^
          413|             collectedImports = collectStructuredModules module._file module.key module.imports args;

       … while calling 'loadModule'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:348:53:

          347|       # Like unifyModuleSyntax, but also imports paths and calls functions if necessary
          348|       loadModule = args: fallbackFile: fallbackKey: m:
             |                                                     ^
          349|         if isFunction m then

       … from call site

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:349:12:

          348|       loadModule = args: fallbackFile: fallbackKey: m:
          349|         if isFunction m then
             |            ^
          350|           unifyModuleSyntax fallbackFile fallbackKey (applyModuleArgs fallbackKey m args)

       … while calling 'isFunction'

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/trivial.nix:991:16:

          990|   */
          991|   isFunction = f: builtins.isFunction f ||
             |                ^
          992|     (f ? __functor && isFunction (f.__functor f));

       … while calling anonymous lambda

         at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:518:35:

          517|       context = name: ''while evaluating the module argument `${name}' in "${key}":'';
          518|       extraArgs = mapAttrs (name: _:
             |                                   ^
          519|         addErrorContext (context name)

       … while evaluating the module argument `inputs' in ":anon-5:anon-1":

       error: infinite recursion encountered

       at /nix/store/fpivx4sjcp2vk4rp9nhliln5cwcp3kc6-source/lib/modules.nix:520:28:

          519|         addErrorContext (context name)
          520|           (args.${name} or config._module.args.${name})
             |                            ^
          521|       ) (functionArgs f);

I have no idea what am I looking at here. Please help :slight_smile:

Where should I add extraSpecialArgs please?

In home-manager/default.nix, like this:

# Add inputs to module args
{ inputs, nixmobar, ... }:
{
  home-manager = {
    extraSpecialArgs = {
      inherit inputs;
    };
    users.refaelsh = import ./home.nix;
  };
}
1 Like

This worked. Thank you very much.
2 questions please:

  1. How did you know to arrive from error: infinite recursion encountered to extraSpecialArgs?
  2. I tried having the module be an output of the Nixmobar flake and use it as input in my NixOS flake, as per the original question, but now I am getting this error:
error: attribute 'nixmobar' missing

       at /nix/store/4a0nc9r1hkrg6wvqm8f73yv43742s550-source/home-manager/home.nix:16:5:

           15|     # inputs.self.homeModules.nixmobar
           16|     inputs.nixmobar.homeModules.nixmobar
             |     ^
           17|     ./alacritty.nix

The current state of the dotfiles is here: GitHub - refaelsh/dotfiles at 11797fcac49d834db0037b463bff39d390470464.