Use a custom nix on a flake proyect

On CI we have a problem with nix errors not showing and it got solved with a custom fix to the C++.

The problem now is that flake-compat isn’t accepting the new version of nix and I believe it is because our custom nix is “dirty” for some reason I can’t understand.

Here is a small project reproducing my error: GitHub - hhefesto/dirty-nix-question: `error: in pure evaluation mode, 'fetchTarball' requires a 'sha256' argument` gets triggered when having a custom nix

And you can reproduce locally with:

$ nix build github:hhefesto/dirty-nix-question --show-trace
warning: Using saved setting for 'allow-import-from-derivation = true' from ~/.local/share/nix/trusted-settings.json.
warning: Using saved setting for 'extra-substituters = https://cache.iog.io' from ~/.local/share/nix/trusted-settings.json.
warning: Using saved setting for 'extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=' from ~/.local/share/nix/trusted-settings.json.
trace: WARNING: `cleanSourceWith` called on /nix/store/ljcfgkxva04qy43n8ynl5ydj6hy3151y-source without a `name`. Consider adding `name = "ljcfgkxva04qy43n8ynl5ydj6hy3151y-source";`
error: in pure evaluation mode, 'fetchTarball' requires a 'sha256' argument

       … while realising the context of a path

       at /nix/store/nvrfhgwqs57vj2gsmw9rgvlf6pjg8l9v-source/default.nix:1:2:

            1| (import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") {
             |  ^
            2|   src = ./.;

       … while evaluating the file '/nix/store/nvrfhgwqs57vj2gsmw9rgvlf6pjg8l9v-source/default.nix':

       … while evaluating the attribute 'buildPackages.nix'

       at /nix/store/ljcfgkxva04qy43n8ynl5ydj6hy3151y-source/flake.nix:26:11:

           25|         (final: prev: {
           26|           nix = nix-patched.packages.x86_64-linux.default;
             |           ^
           27|         })

       … while calling 'getOutput'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/attrsets.nix:832:23:

          831|   */
          832|   getOutput = output: pkg:
             |                       ^
          833|     if ! pkg ? outputSpecified || ! pkg.outputSpecified

       … from call site

       … while calling anonymous lambda

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/strings.nix:160:68:

          159|     paths:
          160|     concatStringsSep ":" (map (path: path + "/" + subDir) (filter (x: x != null) paths));
             |                                                                    ^
          161|

       … from call site

       … while calling 'makeSearchPath'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/strings.nix:159:5:

          158|     # List of base paths
          159|     paths:
             |     ^
          160|     concatStringsSep ":" (map (path: path + "/" + subDir) (filter (x: x != null) paths));

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/strings.nix:179:11:

          178|     # List of packages
          179|     pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
             |           ^
          180|

       … while calling 'makeSearchPathOutput'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/strings.nix:179:5:

          178|     # List of packages
          179|     pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
             |     ^
          180|

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/overlays/bootstrap.nix:1098:61:

         1097|           for prog in stack-to-nix cabal-to-nix plan-to-nix; do
         1098|             wrapProgram "$out/bin/$prog" --prefix PATH : "${final.lib.makeBinPath tools}"
             |                                                             ^
         1099|           done

       … while evaluating the attribute 'buildCommand' of the derivation 'nix-tools'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/pkgs/stdenv/generic/make-derivation.nix:294:7:

          293|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          294|       name =
             |       ^
          295|         let

       … while evaluating the attribute 'buildInputs' of the derivation 'stack-repos'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/pkgs/stdenv/generic/make-derivation.nix:294:7:

          293|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          294|       name =
             |       ^
          295|         let

       … while realising the context of a path

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/stack-cache-generator.nix:56:32:

           55|
           56|     repos = builtins.fromJSON (builtins.readFile (evalPackages.runCommand "stack-repos" {
             |                                ^
           57|         buildInputs = [ nix-tools ];

       … while calling anonymous lambda

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/stack-cache-generator.nix:3:1:

            2|
            3| { src
             | ^
            4| , stackYaml    ? "stack.yaml"

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/overlays/haskell.nix:926:34:

          925|                   // final.lib.optionalAttrs (args.cache == null) { inherit cache; });
          926|                 generatedCache = genStackCache args;
             |                                  ^
          927|                 cache = if args.cache != null then args.cache else generatedCache;

       … while calling 'optionalString'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/strings.nix:227:5:

          226|     # String to return if condition is true
          227|     string: if cond then string else "";
             |     ^
          228|

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/call-stack-to-nix.nix:80:7:

           79|     ''}
           80|     ${evalPackages.lib.optionalString (cache != null) ''
             |       ^
           81|       cp ${mkCacheFile cache}/.stack-to-nix.cache* $out${subDir'}

       … while evaluating the attribute 'buildCommand' of the derivation 'haskell-project-stack-to-nix-pkgs'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/pkgs/stdenv/generic/make-derivation.nix:294:7:

          293|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          294|       name =
             |       ^
          295|         let

       … while realising the context of a path

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/import-and-filter-project.nix:18:13:

           17|   projectSubDir'' = if projectSubDir == "" then "" else projectSubDir + "/"; # With trailing /
           18|   project = import "${projectNix}${projectSubDir'}";
             |             ^
           19| in project // {

       … while calling anonymous lambda

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/import-and-filter-project.nix:5:1:

            4| { pkgs, haskellLib }:
            5| { projectNix, sourceRepos, src }:
             | ^
            6| let

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/overlays/haskell.nix:933:32:

          932|               pkg-set = mkStackPkgSet
          933|                 { stack-pkgs = importAndFilterProject callProjectResults;
             |                                ^
          934|                   pkg-def-extras = (args.pkg-def-extras or []);

       … while calling 'imap1'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/lists.nix:117:14:

          116|   */
          117|   imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
             |              ^
          118|

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:398:73:

          397|           };
          398|         in parentFile: parentKey: initialModules: args: collectResults (imap1 (n: x:
             |                                                                         ^
          399|           let

       … while calling 'filterModules'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:413:36:

          412|       # modules recursively. It returns the final list of unique-by-key modules
          413|       filterModules = modulesPath: { disabled, modules }:
             |                                    ^
          414|         let

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:426:7:

          425|     in modulesPath: initialModules: args:
          426|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
             |       ^
          427|

       … while calling anonymous lambda

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:425:37:

          424|
          425|     in modulesPath: initialModules: args:
             |                                     ^
          426|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:258:25:

          257|       merged =
          258|         let collected = collectModules
             |                         ^
          259|           (specialArgs.modulesPath or "")

       … while calling 'reverseList'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/lists.nix:406:17:

          405|   */
          406|   reverseList = xs:
             |                 ^
          407|     let l = length xs; in genList (n: elemAt xs (l - n - 1)) l;

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:262:33:

          261|           ({ inherit lib options config specialArgs; } // specialArgs);
          262|         in mergeModules prefix (reverseList collected);
             |                                 ^
          263|

       … while calling 'byName'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:542:25:

          541|       */
          542|       byName = attr: f: modules:
             |                         ^
          543|         zipAttrsWith (n: concatLists)

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:559:21:

          558|       # an attrset 'name' => list of submodules that declare ‘name’.
          559|       declsByName = byName "options" (module: option:
             |                     ^
          560|           [{ inherit (module) _file; options = option; }]

       … while evaluating the attribute 'matchedOptions'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:637:14:

          636|     in {
          637|       inherit matchedOptions;
             |              ^
          638|

       … while calling 'mapAttrsRecursiveCond'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/attrsets.nix:530:5:

          529|     # Attribute set to recursively map over.
          530|     set:
             |     ^
          531|     let

       … from call site

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:270:28:

          269|           # For definitions that have an associated option
          270|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                            ^
          271|

       … while evaluating the attribute 'config'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/modules.nix:346:9:

          345|         options = checked options;
          346|         config = checked (removeAttrs config [ "_module" ]);
             |         ^
          347|         _module = checked (config._module);

       … while evaluating the attribute 'hsPkgs'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/overlays/haskell.nix:945:43:

          944|                 project = addProjectAndPackageAttrs {
          945|                   inherit (pkg-set.config) hsPkgs;
             |                                           ^
          946|                   inherit pkg-set;

       … while evaluating the attribute 'hsPkgs'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/overlays/haskell.nix:716:15:

          715|               # Haskell packages
          716|               hsPkgs = final.lib.mapAttrs (packageName: package':
             |               ^
          717|                 if package' == null

       … while calling 'filterAttrs'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/attrsets.nix:305:5:

          304|     # The attribute set to filter
          305|     set:
             |     ^
          306|     listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:105:31:

          104|   isProjectPackage = p: p.isProject or false;
          105|   selectProjectPackages = ps: lib.filterAttrs (n: p: p != null && isLocalPackage p && isProjectPackage p) ps;
             |                               ^
          106|

       … while calling 'selectProjectPackages'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:105:27:

          104|   isProjectPackage = p: p.isProject or false;
          105|   selectProjectPackages = ps: lib.filterAttrs (n: p: p != null && isLocalPackage p && isProjectPackage p) ps;
             |                           ^
          106|

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:506:29:

          505|           selectPackages ? haskellLib.selectProjectPackages
          506|         , haskellPackages ? selectPackages project.hsPkgs
             |                             ^
          507|         , packages ? mkFlakePackages haskellPackages

       … while calling 'mapAttrsToList'

       at /nix/store/5yr805gxxxaq4xfdrwgnf19ws59sm7n5-source/lib/attrsets.nix:478:5:

          477|     # Attribute set to map over.
          478|     attrs:
             |     ^
          479|     map (name: f name attrs.${name}) (attrNames attrs);

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:429:22:

          428|   mkFlakePackages = haskellPackages: builtins.listToAttrs (
          429|     lib.concatLists (lib.mapAttrsToList (packageName: package:
             |                      ^
          430|         lib.optional (package.components ? library)

       … while calling 'mkFlakePackages'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:428:21:

          427|   # Flake package names that are flat and match the cabal component names.
          428|   mkFlakePackages = haskellPackages: builtins.listToAttrs (
             |                     ^
          429|     lib.concatLists (lib.mapAttrsToList (packageName: package:

       … from call site

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:507:22:

          506|         , haskellPackages ? selectPackages project.hsPkgs
          507|         , packages ? mkFlakePackages haskellPackages
             |                      ^
          508|         , apps ? mkFlakeApps haskellPackages

       … while evaluating the attribute 'packages'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:517:14:

          516|       }: {
          517|       inherit
             |              ^
          518|           # Used by:

       … while evaluating the attribute 'packages'

       at /nix/store/apmxc977sc6ikq8r032385f41rrsiqq6-source/lib/default.nix:382:7:

          381|       inherit name;
          382|       value =
             |       ^
          383|         # This favours the first item (`a`) in the case of duplicates

Any help is greatly appreciated and thank you very much for your time < 3

The custom nix derivation can be found at GitHub - neilmayhew/nix at missing-error-messages

There is also a PR with info on the custom nix: Sort build results by severity and message error body by EduardoLR10 · Pull Request #7917 · NixOS/nix · GitHub

The build is failing because the default.nix in the nix repo (both the one used in your flake and the upstream one) is not specifying a sha256 attribute to fetchTarball when importing flake-compat:

(import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") {
  src = ./.;
}).defaultNix

As the error message states, using fetchTarball (or any other url fetcher) without a sha256 hash is invalid in pure evaluation mode. You could of course switch to the impure evaluation mode :grimacing:, but you don’t have to: The README in the flake-compat repo shows an expression which reads the sha256 from the flake.lock file:

  (
    let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
    fetchTarball {
      url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
      sha256 = lock.nodes.flake-compat.locked.narHash;
    }
  )
  { src = ./.; }
).defaultNix

For this to work, this flake-compat also has to be added to flake.nix. I tested this by forking the nix repo from your flake: GitHub - sysedwinistrator/nix at flake-compat-fix.
The build seems to run fine now, although I’m not going to wait for the build to finish :sweat_smile:

1 Like

BTW, I opened a PR to fix this upstream, it just got merged: add flake-compat to flake.nix and use sha256 in default.nix by sysedwinistrator · Pull Request #7989 · NixOS/nix · GitHub

1 Like