I ran into a big foot-gun. I’m not sure if this is intentional and documented anywhere, or if it’s a genuine bug.
It seems that lib.strings.trim somehow discards the string context of its input. This has the effect that store paths interpolated into a trimmed string in some derivation do not become part of the derivation’s closure.
(For a concrete example, you might be inclined to use this to copy resource files into the store when creating configuration files using environment.etc."some/path".text. Because of this quirk, the resource file will be copied into the store upon evaluation, but it won’t be included in the system closure.)
Here’s a minimal working example.
I’ve tested it both on the current NixOS 26.05 beta (Nix 2.34.7, Nixpkgs rev 705e9929918b43bd7b715dc0a878ac870449bb03), and on NixOS 25.11 (Nix 2.31.5, Nixpkgs rev 25f538306313eae3927264466c70d7001dcea1df).
(Running nix repl using the 25.11 version of the tool and with the 25.11 Flake here:)
$ nix run github:nixos/nixpkgs/nixos-25.11#nix repl github:nixos/nixpkgs/nixos-25.11
Nix 2.31.5
Type :? for help.
Loading installable 'github:nixos/nixpkgs/nixos-25.11#'...
Added 7 variables.
checks, devShells, formatter, htmlDocs, legacyPackages, lib, nixosModules
nix-repl> pkgs=legacyPackages.x86_64-linux
nix-repl> builtins.getContext "${pkgs.hello}"
{
"/nix/store/8550ijfw8imvqnky30gwdvwlidq3g42b-hello-2.12.2.drv" = { ... };
}
nix-repl> builtins.getContext (lib.strings.trim "${pkgs.hello}")
{ }
Since I can’t find this behavior documented anywhere and the source of trim doesn’t appear to be using any obvious unsafeDiscardStringContext calls or similar, this sure does feel like it could be a bug. But I wanted to ask before creating a report.
Does anyone have some idea of what could be causing this? If this is expected: Are there other classes of string functions that can cause the context to be discarded, that you should look out for?