What does documentation.nixos.includeAllModules actually do?

After setting this option (recommended elsewhere) my build starts failing with

function ‘anonymous lambda’ called with unexpected argument ‘utils’

in any one of several files included in my configuration. Before figuring out whether this is worth fixing, I tried looking at its description, but that’s not very helpful. What does it actually do? And what is baseModules?

I’ve looked for all the relevant keywords (“utils”, “baseModules”, “base modules”) in The NixOS manual and the NixOS modules wiki page, without finding anything.

Probably one of those cases where looking into the code is the only chance to grasp exactly what happens. I haven’t done that myself in this case, but I think I can say a lot from my own experience.

I’m unsure where to start, so just in case:
The documentation.nixos options are controlling if and what is included in the NixOS manual built into your own system. Essentially it is the same as the official one. In its appendix (or also in man configuration.nix) you will find a list of nearly all(*) available options.

These are a lot of options, mostly unmaintained until something breaks or needs expansion. This includes something simple as options having broken descriptions, types or defaults. And because of Nix lazy evaluation, these errors are hidden until the option is actually required for building your system.

So, for building the options list, the doc builder reuses the module system, iterates over every option, and by that triggers the evaluation of every option’s description, type and default. And funny enough, if an option is set, you do not need to evaluate its description, default and not even a type’s human description. This makes it really easy to define options, which work for system evaluation but which cannot be rendered into the docs.

In my experience most (maybe all) official NixOS modules should have a working documentation (from this I assume baseModules includes all official NixOS modules), but non-official 3rd-party modules tend to have broken documentation. So to make it possible for you to have a basic documentation on your systems while using 3rd-party modules, you can restrict the docs to the baseModules.

But, to make it more weird: your whole configuration is also a module. And e.g. in case of an option A not defining defaultText but having a default depending on another option B, the doc will reflect the actual value of B as A‘s default. (In these cases, defaultText of B should also be set.) Your configuration is not a baseModule so this can only be happen with includeAllModules enabled, as the doc-builder can then no longer differentiate between “module modules” and “your config module(s)”.

For completeness: the release notes of 19.09 mentioned here that includeAllModules was seen as experimental because even official modules had broken documentation. I assume/hope this has changed in the last 5 years.

PS: In my experience, an option’s default is most often the culprit, as it can be that the default works just fine with other options set, but not when all options have only their defaults configured. That’s one reason why options can define a defaultText attribute to overwrite what is rendered into the docs.

(Disclaimer for anyone: this is CC-0, feel free to copy/reuse for publishing it in the wiki or elsewhere.)

1 Like