NixOS wsl2 flake user groups and user types

Hi everyone!

I was used to set up my nixos distro on wsl2 with configuration.nix until I recently discovered a flake the community tutorial suggested. That solved a problem I had previously with an impure flake I had to bypassed with --impure flag in nix-rebuild --flake.

Right now I don’t have any idea about how to set group users and set either isSystemUser or isNormalUser as this error wants me to:

error:
       Failed assertions:
       - Exactly one of users.users.wavesinaroom.isSystemUser and users.users.wavesinaroom.isNormalUser must be set.

       - users.users.wavesinaroom.group is unset. This used to default to
       nogroup, but this is unsafe. For example you can create a group
       for this user with:
       users.users.wavesinaroom.group = "wavesinaroom";
       users.groups.wavesinaroom = {};
Command 'nix --extra-experimental-features 'nix-command flakes' build --print-out-paths '/home/wavesinaroom/waves_nixconfig#nixosConfigurations."nixos".config.system.build.toplevel' --no-link' returned non-zero exit status 1.

This is my flake:

{
  description = "Waves in a room set up";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
    home-manager = {
      url = "github:nix-community/home-manager/release-25.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { self, nixpkgs, home-manager, nixos-wsl, ... }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          nixos-wsl.nixosModules.default
          {
            system.stateVersion = "25.05";
            wsl.enable = true;
          }
          home-manager.nixosModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users.wavesinaroom = import ./home.nix;
              backupFileExtension = "backup";
            };
          }
        ];
      };
    };
  };
}

This is my home manager:

{ lib, config, pkgs, ... }:
let
  dotfiles = "${config.home.homeDirectory}/waves-dotfiles/config";
  create_symlink = path: config.lib.file.mkOutOfStoreSymlink path;
  configs = { };
in {
  imports = [
    ./modules/nvim/nvim.nix
    ./modules/bash.nix
    ./modules/git.nix
    ./modules/direnv.nix
    ./modules/tmux/tmux.nix
  ];
  xdg.configFile = builtins.mapAttrs (name: subpath: {
    source = create_symlink "${dotfiles}/${subpath}";
    recursive = true;
  }) configs;
  home.username = "wavesinaroom";
  home.homeDirectory = lib.mkDefault "/home/wavesinaroom";
  home.packages = with pkgs; [ glab w3m ];
  home.stateVersion = "25.05";
}

I did a couple of tries in my homemanager.nix but I didn’t know how to do that. The problem with my flake is that I’m importing homemanager.nix so I can’t add more attributes. Sorry, I’m not sure what to do

Can anyone lend me a hand with this please?

Edit

I just realized I didn’t add configuration.nix, here you go:


{ config, lib, pkgs, ... }:

{
  imports = [
    # include NixOS-WSL modules
    <nixos-wsl/modules>
  ];

  wsl.enable = true;
  wsl.defaultUser = "wavesinaroom";
  users.users.wavesinaroom.isSystemUser = true;
  programs.git = {
    enable = true;
    prompt.enable = true;
  };

  programs.neovim = {
    enable = true;
    viAlias = true;
    vimAlias = true;
    defaultEditor = true;
  };
  nix.settings.experimental-features = [ "nix-command" "flakes" ];
  system.stateVersion = "25.05"; # Did you read the comment?
}

users.users.wavesinaroom.isSystemUser = true; is in this file and still I get the error. Now I remember that’s the reason what I’m asking here what’s going on here.

I don’t know anything about WSL, but you definitely don’t want your personal user to be a system user. Most likely it’s being set as a normal user by something else, and adding that line is causing your issue.

hi @wavesinaroom seems you just need to import configuration.nix in your flake.nix

{
  description = "Waves in a room set up";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
    home-manager = {
      url = "github:nix-community/home-manager/release-25.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { self, nixpkgs, home-manager, nixos-wsl, ... }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix # or ./some/relative/path/to/configuration.nix
          nixos-wsl.nixosModules.default
          {
            ...
          }
          home-manager.nixosModules.home-manager
          {
            home-manager = {
              ...
            };
          }
        ];
      };
    };
  };
}

Thanks! That makes total sense. I changed it for users.users.wavesinaroom.isNormalUser = true; in my flake

Thanks for taking time! Actually I added the user straight into my flake in the following way. Unfortunately importing my ./configuration.nix file yields an impure expression because of imports = [<nixos-wsl/modules>].

So the solution to the problem is:

        modules = [
          nixos-wsl.nixosModules.default
          {
            system.stateVersion = "25.05";
            wsl.enable = true;
            users.users.wavesinaroom.isNormalUser = true;
          }
          # Home manager code goes here
        ]

You can do that, actually, but the solution looks a bit different:

# flake.nix
{
  # inputs, description, ...
  outputs = { nixpkgs, ... } @ inputs: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      # Note that specifying the system is deprecated,
      # that should be done by `hardware-configuration.nix`
      specialArgs = { inherit inputs; };
      modules = [
        ./configuration.nix
      ];
    };
  };
}
# configuration.nix
{ inputs, ... }: {
  imports = [
    inputs.nixos-wsl.nixosModules.default
    inputs.home-manager.nixosModules.home-manager
    ./hardware-configuration.nix
  ];

  home-manager = {
    # ...
  };

  wsl = {
    # ...
  };

  # And of course any other config, like
  # `system.stateVersion`, `users.users`, ...
}

You can then obviously also break out the wsl/home-manager config into a separate module, and generally do pretty much anything you like within the confines of the module system, instead of writing all your config in inline modules.

Both work, obviously, but I prefer this since it keeps the business logic outside flake.nix, which really is just intended as an entrypoint.

I really dislike the trend of cramming loads of logic into flake.nix; I think it’s mostly done by people who don’t understand the module system, or don’t want to specify two files for documentation.

1 Like

Thanks a lot! Your point is worth considering. Now that I think of it, yeah flake.nix should be big at all