`builtins.getFlake`: file has an unsupported type

I’m trying to use builtins.getFlake to get some nixosModules and legacyPackages in a non-flake setup locally for nixosTests and my local repo has a postgres directory containing a unix socket in it that we use for development, which is obviously in the .gitignore. This isn’t a problem for our flake in the root because flakes take git into account, but when using getFlake I get an error that looks like this:

error: file '/.../owner/repo/postgres/.s.PGSQL.5432' has an unsupported type

You would think that since it is a flake related function, it would behave the same as a flake, eg. copy to the store based on vcs rules, but its actually copying everything and not taking that into account.

I’ve also tried using builtins.fetchGit and builtins.path to filter it out, but you cannot use builtin file source filters because getFlake cannot accept a store path, so unfortunately that doesn’t work either.

I found this issue which seems relevant: Flakes using paths do not infer `git+file:` despite documentation to that effect · Issue #5836 · NixOS/nix · GitHub

How exactly are you using getFlake? Please share the exact function call, without obfuscations or omissions.

I have tried the following:

  flake = builtins.getFlake "git+file:///${../..}";
  flake = builtins.getFlake "path:${../..}";
error: file '/.../owner/repo/postgres/.s.PGSQL.5432' has an unsupported type

And also:

  flake = builtins.getFlake (builtins.path {
    path = ../..;
    filter = path: _: !baseNameOf path == "postgres";
  });
  flake = builtins.getFlake (builtins.fetchGit {
    url = ../..;
  }).outPath;
error: the string '/nix/store/k66x2bky5rldgjh9g5ag7213bzp9l2fm-source' is not allowed to refer to a store path (such as 'k66x2bky5rldgjh9g5ag7213bzp9l2fm-source')

The problem here is ../.., that copies to the store before any flake mechanism would be able to filter.

Please use a hardcoded path outside of the store.

If I could do that then I would… An absolute path in this case would not be reproducible between developers working on the project. A relative path is the right choice since the flake it is referencing is relative to the project directory its contained in.

Then use an environment variable. Who even tells you that I clone the other thing to the same location? Its a flake at the end, as long as I do not actively work on it, I do not really see a reason to clone it, I’d prefer to just use it from remote.

The alternative of course, is to get the socket out of the local clone.

I think this could be solved by allowing getFlake to accept a store path so that fetchGit or path could be used. I doubt that it will happen though, so probably the path of least resistance in this case is just use a flake and have the root flake as an input.

Apparently, this behavior is being phased out of flakes as well:

warning: Fetching Git repository 'file:../..', which uses a path relative to the current directory. This is not supported and will stop working in a future release. See https://github.com/NixOS/nix/issues/12281 for details.

So this solution will not work for much longer:

# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    myLocalFlake = {
      url = "git+file:../..";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}

getFlake is broken, subflakes don’t work well, and what you want is also unsupported. You’d have to stick to absolute paths.

Okay, so relative paths are not being phased out. The issue linked there says to just use the relative path, not git+file (which is being phased out). So this works:

# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    myLocalFlake = {
      url = "../..";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}

IMO builtins.getFlake should work the same way. This could probably be resolved by allowing getFlake to accept a path or string, where a path is automatically resolved how flakes already work. @roberth I’m not sure if you’re the right person to tag, but since you had opened the issue mentioned in the warning output I hope you don’t mind me tagging you in this.

There is a difference between git+file:../.. as a flake input and git+file:${../..} as an argument to getFlake.

The former will be seen by nix as that, the latter will cause to get a copy of ../.. to the store as is, and only then call getFlake with the resulting store path.

The problem in general is not, that getFlake doesn’t accept store paths, but more that the path based approaches you have break context of the string, and that is forbidden.

1 Like