IFD for home-manager modules: infinite recursion

I’m experimenting with a literate config where I define home-manager modules in Org-Mode, create a derivation to tangle the Org to Nix, and then import-from-derivation to compose the resulting Nix into my home-manager config. Even before introducing Org, I’m hitting problems. I expect this to create a home-manager config with the hello package, but it’s failing with infinite recursion:

{ config, pkgs, ... }:

let
  # In the real world, this is an org tangle.
  hello = pkgs.writeText "hello" ''
    { pkgs, ... }: {
      home.packages = [ pkgs.hello ];
    }
  '';

  # This is the import-from-derivation
  helloModule = (import hello);
in {
  # $ home-manager -I home-manager=https://github.com/nix-community/home-manager/archive/release-21.11.tar.gz build -f default.nix && ./result/home-path/bin/hello
  # error: infinite recursion encountered

  #        at /nix/store/hh88z3yigsill682cw1ifv2qhyr9jxz7-nixpkgs-22.05pre373991.b283b64580d/nixpkgs/lib/modules.nix:496:28:

  #           495|         builtins.addErrorContext (context name)
  #           496|           (args.${name} or config._module.args.${name})
  #              |                            ^
  #           497|       ) (lib.functionArgs f);
  # (use '--show-trace' to show detailed location information)
  imports = [ helloModule ];
}

My end vision is a flake with some Org, whose outputs include a package for my website (exported from the Org) and my system config (tangled and imported from the Org). Even just the above would be nice progress.

Nix is 2.8.0, OS is MacOS 12.3.1. Thanks for any insight!

I got similar working as a literate flake. Whether it’s a good idea or not is a different question.

The problem is that you’re using pkgs to define imports via the import of hello which is defined by pkgs.writeText.
pkgs is defined after all modules have been combined (since you could declare overlays inside modules). In order to define pkgs, all modules must be combined which requires all imports to be handled and for your module’s imports, you’d have to define pkgs.

pkgs is defined in terms of pkgs.writeText: Infinite recursion.

Try builtins.toFile instead of pkgs.writeText.

I’d highly recommend you to find a solution that doesn’t require IFD though. Perhaps “compile”/export your literate config into non-literal nix files in a separate, imperative step.

1 Like