Flake that works in repl, but not when building

The following flake.nix works fine when I load it using nix repl, but not when I try to build it with nix build.

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

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      with nixpkgs.legacyPackages.x86_64-linux;
      let
        isArthur = pkg:
          pkg.name == "arthur" && pkg.os == "linux" && pkg.arch == "amd64";
      in {
        packages.arthur = stdenv.mkDerivation rec {
          pname = "arthur";
          src = fetchurl {
            url =
              "s3://manifests/stable/manifest.json?region=eu-central-1";
            sha256 =
              "sha256:17bd9djdp5401ixglbw7jxw4a06w01imcc36n3dzrxiapfnarrny";
          };
          manifest = builtins.fromJSON (builtins.readFile src.outPath);
          version = manifest.version;
          arthur_pkg =
            builtins.elemAt (builtins.filter isArthur manifest.packages) 0;
          dontUnpack = true;
          dontBuild = true;

          installPhase = ''
            echo $version
          '';
        };

        defaultPackage = self.packages.${system}.arthur;
      });
}

In nix repl:

% nix repl
Welcome to Nix 2.6.0. Type :? for help.

nix-repl> :lf .
warning: Git tree '/home/haddock/projs/arthur-v2' is dirty
Added 10 variables.

nix-repl> outputs.defaultPackage.x86_64-linux.arthur_pkg
[0/1 built] { arch = "amd64"; executable = true; name = "arthur"; os = "linux"; public = false; sha256 = "10ffce33013f8106a51f0b06812df17876b1197aca97b78f1b4b248b072c6dd0"; size = 5283721; }

but when trying to build it:

% nix build
warning: Git tree '/home/haddock/projs/arthur-v2' is dirty
error: cannot coerce a set to a string

       at /nix/store/cxdpw8siygg8vp9w07i703lvkgm9889z-source/flake.nix:24:11:

           23|           version = manifest.version;
           24|           arthur_pkg =
             |           ^
           25|             builtins.elemAt (builtins.filter isArthur manifest.packages) 0;
(use '--show-trace' to show detailed location information)

I’m not sure what’s going on here, why the attempt to coerce it to a string a all?

Try evaluating with --impure which I think the repl does. If that works then the error is caused by differences between impure and pure evaluation.

No, unfortunately nix build --impure has the same behaviour as nix build :disappointed: