callCabal2Nix with cabal project in other folder breaks in nativeBuildInputs

Hi. I have a very simple flake which should use callCabal2nix to create a shell for a cabal project in a child folder using a custom GHC environment. The reason this is needed is that, without the nativeBuildInputs extended with a customGhc environment that has access to the propagatedBuildInputs of the project, the zlib library (a C dependency) is not found. But having a customGhc be based on a separate folder breaks with this error in callCabal2nix:

error:
       … while calling the 'derivationStrict' builtin

         at /builtin/derivation.nix:9:12: (source not available)

       … while evaluating derivation 'nix-shell'
         whose name attribute is located at /nix/store/ka3vmkgvsn6cj8dywj7n1xl3bm54gxm7-source/pkgs/stdenv/generic/make-derivation.nix:352:7

       … while evaluating attribute 'nativeBuildInputs' of derivation 'nix-shell'

         at /nix/store/ka3vmkgvsn6cj8dywj7n1xl3bm54gxm7-source/pkgs/stdenv/generic/make-derivation.nix:396:7:

          395|       depsBuildBuild              = elemAt (elemAt dependencies 0) 0;
          396|       nativeBuildInputs           = elemAt (elemAt dependencies 0) 1;
             |       ^
          397|       depsBuildTarget             = elemAt (elemAt dependencies 0) 2;

       error: builder for '/nix/store/bghblpsfk9y2f7vvir3bgh99ih7gdwka-cabal2nix-rectify-backend.drv' failed with exit code 1;
       last 1 log lines:
       > cabal2nix: user error (*** Found neither a .cabal file nor package.yaml. Exiting.)

Here’s the flake.nix.

{
  description = "";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {
          inherit system;
        };

        packageName = "rectify-backend";
        haskellPackages = pkgs.haskellPackages;
        cabalPackages = haskellPackages.callCabal2nix packageName ./rectify-backend {};
        cabalPropagated = builtins.filter (d: !(isNull d)) cabalPackages.propagatedBuildInputs;
        customGhc = haskellPackages.ghcWithPackages (ps: cabalPropagated);

      in {
        packages.${packageName} = cabalPackages;

        defaultPackage = self.packages.${system}.${packageName};

        devShells.default = pkgs.mkShell {
          buildInputs = [
            # For Haskell
            haskellPackages.haskell-language-server
            haskellPackages.ghcid
            haskellPackages.cabal-install
          ];

          # For Haskell's C dependencies - blas, lapack and zlib
          nativeBuildInputs = [
            customGhc
          ];
        };
      }
    );
}

This works if the .cabal file is in the same folder as flake.nix though. But I don’t know why callCabal2Nix is looking in the wrong place. My file structure is this:

.
├── cabal.project
├── flake.lock
├── flake.nix
├── hmm.nix
└── rectify-backend
    ├── app
    │   ├── Ex.hs
    │   └── Main.hs
    ├── rectify-backend.cabal
    └── src
        ├── Effect.hs
        ├── Oleg.hs
        ├── RandoNeur.hs
        ├── ServerEx.hs
        ├── SimulatedAnnealing.hs
        └── Surface.hs

cabal.project is just packages: */*.cabal and the rectify-backend.cabal file is very plain, here’s the relevant section:

cabal-version:      2.2
name:               rectify-backend

version:            0.1.0.0
synopsis:
homepage:
license:            NONE
author:             Deco
maintainer:         decomuricy@gmail.com
category:           None


executable rectify
  import: defaults
  hs-source-dirs: app
  main-is: Main.hs
  build-depends:
      base
    , rectify-backend
    , servant
    , servant-server
    , warp
    , wai
    , wai-cors
    , wai-websockets
    , websockets
    , servant-websockets
    , aeson
    , rio
    , stm
    , text

I’m not sure what the answer to your question is without diving into your code, but have you considered just using the cabalPackages.env attribute instead of your filtering + ghcWithPackages call? Also, is it kosher to pass that into mkShell’s nativeBuildInputs? I would have thought that mkShell’s inputsFrom (or whatever the argument is called) argument would be more appropriate.

Alternatively, using the normal haskellPackages.shellFor setup seems like it might be simpler for you.

This works if the .cabal file is in the same folder as flake.nix though

Oh, another random thought, but is all your haskell code checked in to your repo?