diff --git a/lib/options.nix b/lib/options.nix
index 627aac24d2fb2..9efc1249e58e9 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -231,7 +231,7 @@ rec {
then true
else opt.visible or true;
readOnly = opt.readOnly or false;
- type = opt.type.description or null;
+ type = opt.type.description or "unspecified";
}
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
diff --git a/nixos/doc/manual/development/option-declarations.section.md b/nixos/doc/manual/development/option-declarations.section.md
index fff06e1ea5ba7..cb5043b528fdd 100644
--- a/nixos/doc/manual/development/option-declarations.section.md
+++ b/nixos/doc/manual/development/option-declarations.section.md
@@ -27,9 +27,10 @@ The function `mkOption` accepts the following arguments.
`type`
-: The type of the option (see [](#sec-option-types)). It may be
- omitted, but that's not advisable since it may lead to errors that
- are hard to diagnose.
+: The type of the option (see [](#sec-option-types)). This
+ argument is mandatory for nixpkgs modules. Setting this is highly
+ recommended for the sake of documentation and type checking. In case it is
+ not set, a fallback type with unspecified behavior is used.
`default`
diff --git a/nixos/doc/manual/from_md/development/option-declarations.section.xml b/nixos/doc/manual/from_md/development/option-declarations.section.xml
index 0eeffae628e1a..c7b62192158c1 100644
--- a/nixos/doc/manual/from_md/development/option-declarations.section.xml
+++ b/nixos/doc/manual/from_md/development/option-declarations.section.xml
@@ -38,9 +38,11 @@ options = {
The type of the option (see
- ). It may be omitted, but
- that’s not advisable since it may lead to errors that are hard
- to diagnose.
+ ). This argument is
+ mandatory for nixpkgs modules. Setting this is highly
+ recommended for the sake of documentation and type checking.
+ In case it is not set, a fallback type with unspecified
+ behavior is used.
diff --git a/nixos/lib/make-options-doc/mergeJSON.py b/nixos/lib/make-options-doc/mergeJSON.py
index 029787a31586c..8e2ea322dc896 100644
--- a/nixos/lib/make-options-doc/mergeJSON.py
+++ b/nixos/lib/make-options-doc/mergeJSON.py
@@ -66,14 +66,21 @@ def unpivot(options: Dict[Key, Option]) -> Dict[str, JSON]:
elif ov is not None or cur.get(ok, None) is None:
cur[ok] = ov
+severity = "error" if warningsAreErrors else "warning"
+
# check that every option has a description
hasWarnings = False
for (k, v) in options.items():
if v.value.get('description', None) is None:
- severity = "error" if warningsAreErrors else "warning"
hasWarnings = True
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr)
v.value['description'] = "This option has no description."
+ if v.value.get('type', "unspecified") == "unspecified":
+ hasWarnings = True
+ print(
+ f"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
+ "https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys.stderr)
+
if hasWarnings and warningsAreErrors:
print(
"\x1b[1;31m" +
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index cf6c9661dc1b0..a51fc53453424 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -194,19 +194,8 @@ let
zone.children
);
- # fighting infinite recursion
- zoneOptions = zoneOptionsRaw // childConfig zoneOptions1 true;
- zoneOptions1 = zoneOptionsRaw // childConfig zoneOptions2 false;
- zoneOptions2 = zoneOptionsRaw // childConfig zoneOptions3 false;
- zoneOptions3 = zoneOptionsRaw // childConfig zoneOptions4 false;
- zoneOptions4 = zoneOptionsRaw // childConfig zoneOptions5 false;
- zoneOptions5 = zoneOptionsRaw // childConfig zoneOptions6 false;
- zoneOptions6 = zoneOptionsRaw // childConfig null false;
-
- childConfig = x: v: { options.children = { type = types.attrsOf x; visible = v; }; };
-
# options are ordered alphanumerically
- zoneOptionsRaw = types.submodule {
+ zoneOptions = types.submodule {
options = {
allowAXFRFallback = mkOption {
@@ -246,6 +235,13 @@ let
};
children = mkOption {
+ # TODO: This relies on the fact that `types.anything` doesn't set any
+ # values of its own to any defaults, because in the above zoneConfigs',
+ # values from children override ones from parents, but only if the
+ # attributes are defined. Because of this, we can't replace the element
+ # type here with `zoneConfigs`, since that would set all the attributes
+ # to default values, breaking the parent inheriting function.
+ type = types.attrsOf types.anything;
default = {};
description = ''
Children zones inherit all options of their parents. Attributes
diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix
index f6e9634909241..87873c8c1e83b 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -62,6 +62,7 @@ in {
};
stateDir = mkOption {
+ type = types.path;
default = "/var/lib/unbound";
description = "Directory holding all state for unbound to run.";
};
diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix
index 710c2d9ca17b6..d205302051e14 100644
--- a/nixos/modules/services/networking/vsftpd.nix
+++ b/nixos/modules/services/networking/vsftpd.nix
@@ -153,6 +153,7 @@ in
userlist = mkOption {
default = [];
+ type = types.listOf types.str;
description = "See .";
};
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 92b3af8527f1b..03fe68fe50589 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -219,6 +219,24 @@ in
session = mkOption {
default = [];
+ type = with types; listOf (submodule ({ ... }: {
+ options = {
+ manage = mkOption {
+ description = "Whether this is a desktop or a window manager";
+ type = enum [ "desktop" "window" ];
+ };
+
+ name = mkOption {
+ description = "Name of this session";
+ type = str;
+ };
+
+ start = mkOption {
+ description = "Commands to run to start this session";
+ type = lines;
+ };
+ };
+ }));
example = literalExpression
''
[ { manage = "desktop";
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index d147155d796c1..db00244ca0afa 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -36,7 +36,7 @@ in
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
- type = types.unspecified // { merge = mergeEqualOption; };
+ type = types.raw;
apply = kernelPackages: kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 1575c0257d1c6..a85a3675e03ec 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -581,7 +581,7 @@ in
else "gzip"
);
defaultText = literalDocBook "zstd if the kernel supports it (5.9+), gzip if not";
- type = types.unspecified; # We don't have a function type...
+ type = types.either types.str (types.functionTo types.str);
description = ''
The compressor to use on the initrd image. May be any of: