Use a reference to a derivation in toFIle

I reference a variable from specialArgs from a toFile invocation
The variable is defined here

And is used here

This works, but if I change the definition to the following it stops working

defaultShell = "${pkgs.zsh}/bin/zsh";

I get the error

error: in 'toFile': the file named 'alacritty.yml' must not contain a reference to a derivation but contains (!out!/nix/store/c8hpkcirzx2a65ygvv19lddxmch1clwy-zsh-5.8.1.drv)

       at /nix/store/3czblpr8birzpzyshmhy7xm6a86sfldl-source/linux/thinkpad/home/themeChanger.nix:15:13:

           14|   alacrittyConf =
           15|     colors: builtins.toFile "alacritty.yml"
             |             ^
           16|       (toAlacrittyJSON ({inherit colors;} // alacrittyCommon));

Why does this restriction exist and what is a better way to reference variables from flake.nix in toFile

In toFile i can write

    shell.program = "{pkgs.zsh}/bin/zsh";  # defaultShell;

Shouldn’t that also produce the error above?

You can create the file in a proper build of a derivation. This is less appealing than a simple “toFile” but allows tracking the runtime dependency. Nixpkgs also has a few things like writeTextFile that make it easy to write a file that has such references in it.

An issue that is related to adding more primitives to Nix for simple derivations: System-agnostic builders · Issue #6697 · NixOS/nix · GitHub

builtins.toFile has a rather unintuitive difference from a derivation-based equivalent like pkgs.writeText. It creates the file in the nix store during evaluation/instantiation rather than during the build/realisation stage. Because of this, you can’t put references to derivation outputs into it, because they haven’t been built yet at the time the file is made (and with ca-derivations enabled, you wouldn’t even know their storepath yet at the time the file is made).

Interestingly, this also means that import (builtins.toFile "test.nix" "1 + 1") doesn’t actually qualify as import-from-derivation and can thus be used as a kind of nix “eval”, though currently it seems to be disallowed in pure evaluation mode…