How to fix `evaluation warning: 'system' has been renamed to/replaced by 'stdenv.hostPlatform.system'`

Issue:

evaluation warning: 'system' has been renamed to/replaced by 'stdenv.hostPlatform.system'

What to do

For this to be fixed you probably have to only replace:
${system} with ${stdenv.hostPlatform.system}
and
${pkgs.system} with ${pkgs.stdenv.hostPlatform.system}
anywhere in your nixos configuration files (this isn’t a regex code to do replacement, it’s parts of nix code).

What NOT to do

You should not replace the word system anywhere you see it, stuff like these should remain as they are:

systemPackages
system.stateVersion
system = "x86_64-linux";
inherit system;

Why did this change occur?

The system attribute in nixpkgs changed because the alias system was dropped.
stdenv.hostPlatform.system makes it clear which system is being used (important for cross-compilation)
Using stdenv.hostPlatform.system means that:

  • you’re deliberately choosing the “host” platfom, which is relevant to cross-compilation
  • you’re picking only system from that (roughly speaking)

The deprecated system alias alone wasn’t that specific (as it not exactly meant “what system I’m on”) so it was deprecated

More info

In case you didn’t manage to fix this, it may be possible that some flake in your system uses the old alias. For that to be fixed you need to contact the flake maintainer to fix this (or create a PR yourself).
To figure out what flake may be causing this, append --option abort-on-warn --show-trace in your nixos rebuild command (if you aren’t using nixos-rebuild maybe try --abort-on-warn --show-trace instead).

Credits

This has been discussed at least twice in the nixos matrix room and hopefully this may help people not to get confused as I did.
Thanks to @K900 and @dramforever for the insight and @aljustiet for taking part in the debugging:)

40 Likes

Thank you for writing the notice in such an accessible way, very much appreciated.

4 Likes

This is an antipattern anyway. It should be replaced.

Also an antipattern. In NixOS config users should be setting nixpkgs.hostPlatform. No it’s not going to fix this warning, but the underlying reasoning is the same: system does not specify the platform explicitly enough, and passing system to lib.nixosSystem has long been deprecated for the same reason.

I expect a warning to eventually come for this antipattern too.

I think you mean --option abort-on-warn true --show-trace and tbh it did not work for me.

What did work for me is prefixing the command with NIX_ABORT_ON_WARN=1 and using --impure if building with flakes (to ensure the envvar is picked up).

EDIT: I’ve figured out why - lix does not have a builtins.warn since it was only added in nix 2.23 and lix branched off at 2.18. Hence my advice is compatible with more nix versions.

TLDR use NIX_ABORT_ON_WARN=1 not the abort-on-warn option.

6 Likes

Woah thanks fod the detailed info!

Thanks for clearing some stuff about those anti-patterns, I (and I suppose many others) tend to copy-paste stuff from guides and it’s hard to detect anti-patterns.

Also nice solution about the --option issue, I might edit the guide above sometimeTM to be more accurate:)

1 Like

What should it be replaced with? I have this in my home-manager flake, I believe it was part of the default setup.

edit: starting here in case anyone wants to help and needs context: dotfiles/flake.nix at 0600905e2d4cd39ecfc4c03928414278f43af425 · bklebe/dotfiles · GitHub

1 Like

I made the assumption that this is referring to a NixOS config; in such a situation, nixpkgs.hostPlatform in your NixOS config would be the correct option to set. Passing system to lib.nixosSystem is what is deprecated.

For home-manager, in the NixOS module case you would just inherit the pkgs from NixOS via home-manager.useGlobalPkgs = true; in your NixOS config.

For standalone, you’re forced to pass in a nixpkgs instance, so what you have is okay, but I think it makes more sense to hardcode it per config output (since different configs can have different systems, and a given config can only ever have one system).

i.e. rather than inherit pkgs; I’d explicitly spell out pkgs = nixpkgs.legacyPackages.aarch64-darwin; if I was making multiple hm configs, since another config might have a different system. Then I would drop the let block. (The legacyPackages output still uses system, so that would be deprecated too - so you can explicitly use pkgs = import nixpkgs { hostPlatform = "aarch64-darwin"; }; - but I think that should be fixed in nixpkgs itself.)

If it’s some other system-dependent output, like packages/devShells, I’d hardcode a list of supported platforms, or use nixpkgs.lib.systems.flakeExposed in a pinch, and use that list to generate the outputs.

3 Likes

That all makes sense! And apologies for any confusion, yeah, I’m not using NixOS — but this was the only thread I could find and I don’t like to ever ignore deprecation warnings in my projects, and it seemed like it could be an opportunity to learn more.

So dropping the let block though, there’s no longer a system or pkgs variable in scope for the rest of the flake. Would you just repeat (e.g.) aarch64-darwin and nixpkgs.legacyPackages.aarch64-darwin wherever those are needed? Sorry if these are pedestrian questions, I’m still pretty new to Nix and don’t have the strongest foundations (I should definitely fix that).

2 Likes

I would repeat it simply because I might have a bunch of macs and linux systems, or x86_64 and ARM systems. Your code isn’t wrong, just a bit inflexible if you end up using other systems.

Either way, whether you use the let or not isn’t related to this deprecation.

2 Likes

Definitely, one of the reasons I have for adopting Nix in the first place is to be able to make some of my config portable across Linux and Mac so I do appreciate this advice.

Ok, I also followed your advice to abort on warn and show the trace, and discovered it was actually only this line that was problematic, and I was just getting confused from the rest of this thread because I had the system variable in my let block. Leaving this here in case somebody else ends up similary confused by this warning.

3 Likes

Just found this article talking about best practices I'm not mad, I'm disappointed, with a nice explanation on why system is being not used anymore.

Also the relevant line for the system attribute: nixpkgs/flake.nix at 332e6030634ce7701496564d4c70ae8209919931 · NixOS/nixpkgs · GitHub

2 Likes

Ok this is amazing. I’d really like to read guides about avoiding anti-patterns. Nix is a language and that means that there many waya to do the same thing, but some ways are more efficient or better, depending on the situation.

Also from.what I gather this guide also tells you how to remove the system = "x86_64-linux"; as an anti-pattern too, interesting. For some reason though, nixos doesnt complain even if Ive kept it, hmm

Might just be an unused variable in whatever context you had it.

Have a look at deadnix.

1 Like

I have it on this line

Hm, I have a nix language server which does some similar tests, but will have to check deadnix at some point.

Maybe we should make a thread about antipatterns one day, seems like a very intersting topic:)

1 Like

While it is an antipattern, it doesn’t mean Nix will complain about it. Referencing pkgs.system was also fine for a long time now, and they decided to deprecate the option slowly (maybe reference an issue on how to do it now, like this post, would be a big help!).

But I agree, having a place to document this would be amazing! Maybe the wiki.nixos.org :wink:

2 Likes

Adding --option abort-on-warn true --show-trace to the rebuild command helped me find the problematic use of pkgs.system in my config. I had to look a couple of steps up in the trace to find it.

3 Likes

I don’t understand how to fix this overlay:

  nixpkgs.overlays = [
    (final: _prev: {
      unstable = import inputs.nixpkgs-unstable {
        inherit (final) system config;
      };
    })
  ];

final is just a nixpkgs instance, so something like

inherit (final) config;
localSystem = final.stdenv.hostPlatform; 

or

inherit (final) config;
localSystem = config.nixpkgs.hostPlatform; 

EDIT: fixed example

2 Likes

I have this in my flake.nix :

modules = [
              host.hardwarePresets
              host.config
              impermanence.nixosModules.impermanence
              agenix.nixosModules.default
              catppuccin.nixosModules.catppuccin
              (
                { pkgs, inputs, ... }:
                {
                  _module.args = {
                    unstablePkgs = import inputs.unstable {
                      inherit (pkgs) config overlays system;
                    };
                  };
                }
              )
];

I tried to convert it to:

modules = [
              host.hardwarePresets
              host.config
              impermanence.nixosModules.impermanence
              agenix.nixosModules.default
              catppuccin.nixosModules.catppuccin
              (
                { pkgs, inputs, ... }:
                {
                  _module.args = {
                    unstablePkgs = import inputs.unstable {
                      inherit (pkgs) config overlays;
                      inherit (pkgs.stdenv) hostPlatform;
                    };
                  };
                }
              )
];

But got a:

 error: attribute 'currentSystem' missing
       at «github:NixOS/nixpkgs/2fad6eac6077f03fe109c4d4eb171cf96791faa4?narHash=sha256-sKoIWfnijJ0%2B9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI%3D»/pkgs/top-level/impure.nix:17:29:
           16|   localSystem ? {
           17|     system = args.system or builtins.currentSystem;
             |                             ^
           18|   },

So I switched to:

modules = [
              host.hardwarePresets
              host.config
              impermanence.nixosModules.impermanence
              agenix.nixosModules.default
              catppuccin.nixosModules.catppuccin
              (
                { pkgs, inputs, ... }:
                {
                  _module.args = {
                    unstablePkgs = import inputs.unstable {
                      inherit (pkgs) config overlays;
                      inherit (pkgs.stdenv.hostPlatform) system;
                    };
                  };
                }
              )
];

Am I doing something stupid ? Should I be doing something else to have access to the unstablePkgs ?

Sorry, yeah, I made the assumptions without testing the code or checking the upstream code.

The function only really processes the localSystem and crossSystem args wrt system, so localSystem = pkgs.stdenv.hostPlatform; or localSystem = config.nixpkgs.hostPlatform instead should work, and matches how config.nixpkgs.* is handled upstream (elaborating an elaborated system should be a no-op).

Fixed my example above as well.

In any case, what you wrote should also work for now.

2 Likes