NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.72k stars 1.51k forks source link

error: attribute '' already defined #7897

Open davidak opened 1 year ago

davidak commented 1 year ago

Describe the bug

When i combine a module option in the style of

nix.settings.max-jobs = 4;

with

nix = {
  settings = {
    cores = 4;
    substituters = [
      "https://cache.nixos.org"
    ];
  };
};

it should get automatically combined, since there is no conflict.

But instead i get an error!

Steps To Reproduce

  1. Add to configuration.nix
  nix.settings.max-jobs = 4;

  nix = {
    settings = {
      cores = 4;
      substituters = [
        "https://cache.nixos.org"
      ];
    };
  };
  1. nixos-rebuild switch
[root@gaming:~]# nixos-rebuild switch --keep-failed 
error: attribute 'settings' already defined at /root/nixos/machines/gaming/configuration.nix:281:5

       at /root/nixos/machines/gaming/configuration.nix:278:3:

          277|
          278|   nix.settings.max-jobs = 4;
             |   ^
          279|
(use '--show-trace' to show detailed location information)
building Nix...
error: attribute 'settings' already defined at /root/nixos/machines/gaming/configuration.nix:281:5

       at /root/nixos/machines/gaming/configuration.nix:278:3:

          277|
          278|   nix.settings.max-jobs = 4;
             |   ^
          279|
(use '--show-trace' to show detailed location information)
building the system configuration...
error: attribute 'settings' already defined at /root/nixos/machines/gaming/configuration.nix:281:5

       at /root/nixos/machines/gaming/configuration.nix:278:3:

          277|
          278|   nix.settings.max-jobs = 4;
             |   ^
          279|
(use '--show-trace' to show detailed location information)

Expected behavior

No error in that case. It is clear what i want. Nix should figure it out!

nix-env --version output

Additional context

Add any other context about the problem here.

Priorities

Add :+1: to issues you find important.

balsoft commented 1 year ago

This would change semantics. While I agree that something like this is useful, I'm wondering if the potential for forward-compatibility breakage is worth it.

eclairevoyant commented 6 months ago

A simpler example for the repro:

nix-repl> :p { a.b.c = 1; a = { b.d = 2; }; }
error: attribute 'b' already defined at «string»:1:20
       at «string»:1:3:
            1| { a.b.c = 1; a = { b.d = 2; }; }
             |   ^

nix-repl> :p { a = { b.d = 2; }; a.b.c = 1; }
{
  a = {
    b = {
      c = 1;
      d = 2;
    };
  };
}

Though the formatting is slightly different between the two versions, this happens in nix 2.21.2 and 2.3.17.

Ironically, since #2089, we have a test to catch a similar but ultimately different case: https://github.com/NixOS/nix/blob/e3a4e40a354e1c2d177541d24d6a86a001fa87c7/tests/functional/lang/parse-okay-mixed-nested-attrs-3.nix#L1-L7

which is more akin to

nix-repl> :p { a.b.c = 1; a.b = { d = 2; }; a = { x.y = 3; }; }
{
  a = {
    b = {
      c = 1;
      d = 2;
    };
    x = { y = 3; };
  };
}

I really cannot convince myself this is working as-intended.