I recently ran into an issue where I got a conflicting subpath error while trying to build a NixOS config that uses home manager and has a custom per user Firefox policy and I got this error:
Last 5 log lines:
> pkgs.buildEnv error: two given paths contain a conflicting subpath:
> `/nix/store/pq4rggp2sy8hlyvm54i47fqwa9prj70c-firefox-147.0.4/lib/firefox/distribution/policies.json' and
> `/nix/store/vpqwalxgaqi87c3ph1kxj4dkkw3dczh0-firefox-147.0.4/lib/firefox/distribution/policies.json'
> hint: this may be caused by two different versions of the same package in buildEnv's `paths` parameter
> hint: `pkgs.nix-diff` can be used to compare derivations
This error message is very helpful in finding out what is wrong by suggesting using nix-diff. In this case my custom Firefox policies conflicting with what I can only assume is the default one.
The assumed default policy content
{"policies":{"DisableAppUpdate":true}}
This error message however is not very helpful in finding out why the conflict happened. As in where can I find the cause, the nix file that caused the unwanted version to be included.
Are there any resources/tools that you can recommend for answering the why is something built question?
Help with my specific conflict is actually not very relevant to my question because I’m interested in finding the method to solve this and similar problems in the future if they occur and finding the solution is incidental. This is the main reason why my configuration is not included in this post.
You’re somehow installing both a default firefox and a modified one simultaneously. At a guess, you’re using the firefox module in home-manager, but also installing firefox in your home.packages. Use one or the other, not both.
your comment accurately describes what went wrong in my case. While the issue is/was real in this case it is meant to serve as context to help clarify what is the difference between the “what went wrong” and “why something went wrong” type of question. The former has a tool suggested for it in the error message, while for the latter I’m not aware of anything similar. This is why the question I meant to ask is the following, which wasn’t addressed in your reply:
Not really. There’s nix why-depends --derivation, but this only tells you the relationship of derivations involved. It won’t get you back to the actual nix code. With experience, tools like this can still help point the way, though.
But for me, the way I answered this came down to knowing buildEnv just isn’t used that much. It’s used for options like nixos’ environment.systemPackages and home-manager’s home.packages, and not a lot else. So that meant the conflict was almost certainly in home.packages, and given the difference you saw in the two derivations, they didn’t seem to be different versions, but rather differently-configured versions. Hence, a module-installed version and a manually installed one, most likely.
The nix language and ecosystem isn’t really tame enough for automated tooling to track down the "why"s very well. The best tools for this are experience, understanding nix/nixpkgs/nixos internals, and testing often, so that when something goes wrong you have a small diff to consider as possible causes. That last suggestion is really the most actionable one I can give you.
nix-tree (3rd party tool) tells you the tree of paths being built. Depending on what path depends on the target package would guide your analysis. For example, if you see system-path depending on your target package, you know that environment .systemPackages is where the package would be referenced. You would then use nixos-option to check the value of environment.systemPackages to see which nix code defines those values.
Not sure about home-manager’s equivalent to nixos-option though.