Accessing submodule options -- "used but not defined"

I’ve been trying to modify an existing nixos module. It has some options bundled in a submodule. I tried to add an assertion on one of these, but I get an error like The option `services.foo.settings.my_option' is used but not defined.

The structure of the module is like

{ config, lib, pkgs, ... }:
let
  cfg = config.services.foo;
  settingsFormat = pkgs.formats.yaml { };
in
{
  options.services.foo = {
    enable = lib.mkEnableOption (lib.mdDoc "Foo");
    settings = lib.mkOption {
      type = lib.types.submodule {
        freeformType = settingsFormat.type;
        options.my_option = lib.mkOption {
          type = lib.types.str;
          example = "example.com";
          description = lib.mdDoc ''
            Foobar
          '';
        };
      };
      default = { };
      description = lib.mdDoc ''
        Foobar
      '';
    };
  };
  config = lib.mkIf cfg.enable {
    assertions = [
      {
        assertion = cfg.settings.my_option == null;
        message = "Can't be null";
      }
    ];
  };
}

Is there some special way to access the options in the submodule?

That error message tells you, that you are reading from an option you haven’t written to.

This means that the option neither has a default, nor has been set explicitely by the user.

2 Likes