Description
Hi!
I ran into an infinite recursion problem while trying to import a (soon-to-be) module from nixos-hardware, this one: NixOS/nixos-hardware#1269
❯ nix flake check
warning: Git tree '/home/jkuball/Git/nix' is dirty
warning: unknown flake output '__functor'
evaluation warning: lib.nixos.evalModules is experimental and subject to change. See nixos/lib/default.nix
error:
… while checking flake output 'nixosConfigurations'
… while calling the 'elemAt' builtin
at /nix/store/jv5rs7mrlhkphzfkjpk6jlddi2g1nm46-source/grow/grow-on.nix:79:11:
78| if length values == 1 || head a then
79| elemAt a 1
| ^
80| else
… while calling the 'head' builtin
at /nix/store/jv5rs7mrlhkphzfkjpk6jlddi2g1nm46-source/grow/grow-on.nix:65:92:
64| v1 = !(isAttrs l && isAttrs r);
65| v2 = if attrPath == ["__std" "ci"] || attrPath == ["__std" "init"] then flatten v else head v;
| ^
66| in [v1 v2];
… while evaluating the module argument `config' in "/nix/store/isjriv0b9spxk3hca9zjpk3clbvvqjr9-source/module.nix":
(stack trace truncated; use '--show-trace' to show the full, detailed trace)
error: infinite recursion encountered
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:245:34:
244| (regularModules ++ [ internalModule ])
245| ({ inherit lib options config specialArgs; } // specialArgs);
| ^
246| in mergeModules prefix (reverseList collected);
I am not sure whether this is helpful, but I have added the full trace below.
nix flake check --show-trace
❯ nix flake check --show-trace
warning: Git tree '/home/jkuball/Git/nix' is dirty
warning: unknown flake output '__functor'
evaluation warning: lib.nixos.evalModules is experimental and subject to change. See nixos/lib/default.nix
error:
… while checking flake output 'nixosConfigurations'
… while calling anonymous lambda
at /nix/store/jv5rs7mrlhkphzfkjpk6jlddi2g1nm46-source/grow/grow-on.nix:73:26:
72| let f = attrPath:
73| l.zipAttrsWith (n: values:
| ^
74| let
… while calling the 'elemAt' builtin
at /nix/store/jv5rs7mrlhkphzfkjpk6jlddi2g1nm46-source/grow/grow-on.nix:79:11:
78| if length values == 1 || head a then
79| elemAt a 1
| ^
80| else
… while calling the 'head' builtin
at /nix/store/jv5rs7mrlhkphzfkjpk6jlddi2g1nm46-source/grow/grow-on.nix:65:92:
64| v1 = !(isAttrs l && isAttrs r);
65| v2 = if attrPath == ["__std" "ci"] || attrPath == ["__std" "init"] then flatten v else head v;
| ^
66| in [v1 v2];
… from call site
at /nix/store/hdayw05q3ba4ax7gql5v49l2la409wmw-source/flake.nix:57:33:
56| {
57| nixosConfigurations = collectSystems self "nixosConfigurations";
| ^
58| darwinConfigurations = collectSystems self "darwinConfigurations";
… while calling '__functor'
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/collect.nix:34:27:
33| renamer = cell: target: "${cell}-${target}";
34| __functor = self: Self: CellBlock:
| ^
35| if builtins.hasAttr CellBlock collectors
… from call site
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/collect.nix:36:10:
35| if builtins.hasAttr CellBlock collectors
36| then collectors.${CellBlock} self.renamer Self
| ^
37| else
… while calling 'walk'
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/collectors/nixosConfigurations.nix:12:10:
11|
12| walk = self:
| ^
13| walkPaisano self cellBlock (system: cell: [
… from call site
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/collectors/nixosConfigurations.nix:13:5:
12| walk = self:
13| walkPaisano self cellBlock (system: cell: [
| ^
14| (l.mapAttrs (target: config: {
… while calling 'walkPaisano'
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:4:39:
3|
4| walkPaisano = self: cellBlock: ops: namer:
| ^
5| l.pipe (
… while calling the 'foldl'' builtin
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:5:5:
4| walkPaisano = self: cellBlock: ops: namer:
5| l.pipe (
| ^
6| l.mapAttrs (system:
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/trivial.nix:131:30:
130| */
131| pipe = builtins.foldl' (x: f: f x);
| ^
132|
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/trivial.nix:131:33:
130| */
131| pipe = builtins.foldl' (x: f: f x);
| ^
132|
… while calling 'collect'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:866:5:
865| pred:
866| attrs:
| ^
867| if pred attrs then
… while calling the 'concatMap' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:870:7:
869| else if isAttrs attrs then
870| concatMap (collect pred) (attrValues attrs)
| ^
871| else
… while calling 'collect'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:866:5:
865| pred:
866| attrs:
| ^
867| if pred attrs then
… while calling the 'concatMap' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:870:7:
869| else if isAttrs attrs then
870| concatMap (collect pred) (attrValues attrs)
| ^
871| else
… while calling 'collect'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:866:5:
865| pred:
866| attrs:
| ^
867| if pred attrs then
… while evaluating a branch condition
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:867:5:
866| attrs:
867| if pred attrs then
| ^
868| [ attrs ]
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:867:8:
866| attrs:
867| if pred attrs then
| ^
868| [ attrs ]
… while calling anonymous lambda
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:16:19:
15| ) [
16| (l.collect (x: x ? name && x ? value))
| ^
17| l.listToAttrs
… in the left operand of the AND (&&) operator
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:16:31:
15| ) [
16| (l.collect (x: x ? name && x ? value))
| ^
17| l.listToAttrs
… from call site
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:16:22:
15| ) [
16| (l.collect (x: x ? name && x ? value))
| ^
17| l.listToAttrs
… while calling anonymous lambda
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:7:27:
6| l.mapAttrs (system:
7| l.mapAttrs (cell: blocks: (
| ^
8| l.pipe blocks (
… while calling the 'foldl'' builtin
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/walkPaisano.nix:8:11:
7| l.mapAttrs (cell: blocks: (
8| l.pipe blocks (
| ^
9| [(l.attrByPath [cellBlock] {})]
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/trivial.nix:131:30:
130| */
131| pipe = builtins.foldl' (x: f: f x);
| ^
132|
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/trivial.nix:131:33:
130| */
131| pipe = builtins.foldl' (x: f: f x);
| ^
132|
… while calling 'filterAttrs'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:646:5:
645| pred:
646| set:
| ^
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
… while calling the 'removeAttrs' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:5:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… while calling the 'filter' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:22:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:30:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… in the argument of the not operator
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:38:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:38:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… while calling anonymous lambda
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/collectors/nixosConfigurations.nix:20:26:
19| (l.mapAttrs (_: transformers.nixosConfigurations))
20| (l.filterAttrs (_: config: config.bee.system == system))
| ^
21| (l.mapAttrs (_: config: config.bee._evaled))
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:647:48:
646| set:
647| removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set));
| ^
648|
… from call site
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/transformers/nixosConfigurations.nix:4:4:
3| root,
4| }: {
| ^
5| evaled,
… while calling 'check'
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:9:11:
8|
9| check = locatedConfig: let
| ^
10| checked = l.nixos.evalModules {
… in the condition of the assert statement
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:28:5:
27| in
28| assert l.isAttrs asserted; {
| ^
29| inherit locatedConfig;
… while calling the 'isAttrs' builtin
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:28:12:
27| in
28| assert l.isAttrs asserted; {
| ^
29| inherit locatedConfig;
… while evaluating a branch condition
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:24:7:
23| asserted =
24| if failedAsserts != []
| ^
25| then throw "\nHive's layer sanitation boundary: \n${l.concatStringsSep "\n" (map (x: "- ${x}") failedAsserts)}"
… while calling the 'map' builtin
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:21:21:
20|
21| failedAsserts = map (x: x.message) (l.filter (x: !x.assertion) checked.config.bee._alerts);
| ^
22|
… while calling the 'filter' builtin
at /nix/store/ziiqwyqp7ybawf6s7h9553qkw9gxnahy-source/src/checks/bee.nix:21:41:
20|
21| failedAsserts = map (x: x.message) (l.filter (x: !x.assertion) checked.config.bee._alerts);
| ^
22|
… while evaluating the attribute 'config.bee._alerts'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:334:9:
333| options = checked options;
334| config = checked (removeAttrs config [ "_module" ]);
| ^
335| _module = checked (config._module);
… while calling the 'seq' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:334:18:
333| options = checked options;
334| config = checked (removeAttrs config [ "_module" ]);
| ^
335| _module = checked (config._module);
… while evaluating a branch condition
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:273:9:
272| checkUnmatched =
273| if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
| ^
274| let
… in the left operand of the AND (&&) operator
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:273:72:
272| checkUnmatched =
273| if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
| ^
274| let
… in the left operand of the AND (&&) operator
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:273:33:
272| checkUnmatched =
273| if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
| ^
274| let
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:270:16:
269| # paths, meaning recursiveUpdate will never override any value
270| else recursiveUpdate freeformConfig declaredConfig;
| ^
271|
… while calling 'recursiveUpdate'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1626:5:
1625| lhs:
1626| rhs:
| ^
1627| recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1627:5:
1626| rhs:
1627| recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
| ^
1628|
… while calling 'recursiveUpdateUntil'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1568:5:
1567| lhs:
1568| rhs:
| ^
1569| let f = attrPath:
… while calling the 'zipAttrsWith' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1578:8:
1577| );
1578| in f [] [rhs lhs];
| ^
1579|
… while evaluating a branch condition
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:263:16:
262| }) merged.unmatchedDefns;
263| in if defs == [] then {}
| ^
264| else declaredConfig._module.freeformType.merge prefix defs;
… while calling the 'map' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:259:22:
258| let
259| defs = map (def: {
| ^
260| file = def.file;
… while evaluating the attribute 'unmatchedDefns'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:695:7:
694| # Transforms unmatchedDefnsByName into a list of definitions
695| unmatchedDefns =
| ^
696| if configs == []
… while calling the 'concatLists' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:702:11:
701| else
702| concatLists (mapAttrsToList (name: defs:
| ^
703| map (def: def // {
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1095:10:
1094| attrs:
1095| map (name: f name attrs.${name}) (attrNames attrs);
| ^
1096|
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1095:16:
1094| attrs:
1095| map (name: f name attrs.${name}) (attrNames attrs);
| ^
1096|
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:702:46:
701| else
702| concatLists (mapAttrsToList (name: defs:
| ^
703| map (def: def // {
… while calling the 'map' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:703:13:
702| concatLists (mapAttrsToList (name: defs:
703| map (def: def // {
| ^
704| # Set this so we know when the definition first left unmatched territory
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/attrsets.nix:1095:23:
1094| attrs:
1095| map (name: f name attrs.${name}) (attrNames attrs);
| ^
1096|
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:688:22:
687| # Propagate all unmatched definitions from nested option sets
688| mapAttrs (n: v: v.unmatchedDefns) resultsByName
| ^
689| # Plus the definitions for the current prefix that don't have a matching option
… while evaluating the attribute 'unmatchedDefns'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:695:7:
694| # Transforms unmatchedDefnsByName into a list of definitions
695| unmatchedDefns =
| ^
696| if configs == []
… while evaluating a branch condition
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:696:9:
695| unmatchedDefns =
696| if configs == []
| ^
697| then
… while calling the 'concatLists' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:640:19:
639| loc = prefix ++ [name];
640| defns = pushedDownDefinitionsByName.${name} or [];
| ^
641| defns' = rawDefinitionsByName.${name} or [];
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:600:21:
599| mapAttrs
600| (n: value:
| ^
601| map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
… while calling the 'map' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:601:19:
600| (n: value:
601| map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
| ^
602| )
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:601:77:
600| (n: value:
601| map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
| ^
602| )
… while calling 'pushDownProperties'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:913:24:
912| */
913| pushDownProperties = cfg:
| ^
914| if cfg._type or "" == "merge" then
… while calling the 'map' builtin
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:917:7:
916| else if cfg._type or "" == "if" then
917| map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
| ^
918| else if cfg._type or "" == "override" then
… from call site
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:917:52:
916| else if cfg._type or "" == "if" then
917| map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
| ^
918| else if cfg._type or "" == "override" then
… while calling 'pushDownProperties'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:913:24:
912| */
913| pushDownProperties = cfg:
| ^
914| if cfg._type or "" == "merge" then
… while evaluating a branch condition
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:914:5:
913| pushDownProperties = cfg:
914| if cfg._type or "" == "merge" then
| ^
915| concatMap pushDownProperties cfg.contents
… while evaluating the attribute 'content'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:1038:25:
1037| { _type = "if";
1038| inherit condition content;
| ^
1039| };
… from call site
at /nix/store/isjriv0b9spxk3hca9zjpk3clbvvqjr9-source/module.nix:3:9:
2| let
3| cfg = config.disko;
| ^
4|
… while calling anonymous lambda
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:513:35:
512| context = name: ''while evaluating the module argument `${name}' in "${key}":'';
513| extraArgs = mapAttrs (name: _:
| ^
514| addErrorContext (context name)
… while evaluating the module argument `config' in "/nix/store/isjriv0b9spxk3hca9zjpk3clbvvqjr9-source/module.nix":
… while evaluating the attribute 'config'
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:245:34:
244| (regularModules ++ [ internalModule ])
245| ({ inherit lib options config specialArgs; } // specialArgs);
| ^
246| in mergeModules prefix (reverseList collected);
error: infinite recursion encountered
at /nix/store/zgzjib5vbxl9l2ridhjfvs1ll6lil8s6-source/lib/modules.nix:245:34:
244| (regularModules ++ [ internalModule ])
245| ({ inherit lib options config specialArgs; } // specialArgs);
| ^
246| in mergeModules prefix (reverseList collected);
I already tried to understand the problem, but I only found out the source of the error. The module extends the nixos boot.loader
by a new option:
options = {
boot.loader.kboot-conf = {
# ...
If I change this to be something top level, like just kboot-conf
, everything is fine. Is it illegal to extend original nixos module options, or is it just something that hive does not support?
Sadly I couldn't get a minimal example to also crash. But I presume it is reproducable by just adding github:KhashayarDanesh/nixos-hardware
to the flake inputs and importing inputs.nixos-hardware.nixosModules.hardkernel-odroid-m1
.
I'd love to get some help, or at least pointers on what to do. The easy way to fix it would probably be just to ask the PR maintainer to change the option name, but that feels wrong to me.
Thanks!