Node2nix: ENOTCACHED when using callPackage instead of import

[ As a concrete example, I’m referencing ethercalc. However, the issue seems to arise with other packages as well. For instance, it does so with whitebophir, which I’m maintaining but having problems to unbreak. ]

I just tried to run ethercalc. Inspired by the rapid initial success with the following four commands…

git clone
cd ethercalc
nix-shell -p nodePackages.node2nix --run "node2nix -i package.json -l package-lock.json"
nix-build -A package

…I then wanted to add ethercalc to the system environment in my configuration.nix:

environment.systemPackages = [ (callPackage /root/ethercalc {}).package ];

However, this fails with npm ERR! code ENOTCACHED.

After a bit of trial and error (not really knowing what I was doing – I don’t really know npm nor the Nix approach to npm packages), I stumbled on the workaround to use import instead of callPackage, such as: = "${(import /root/ethercalc {}).package}/bin/ethercalc";

This works just fine. However, I fail to understand the difference. Can anyone enlighten me? :slight_smile:

callPackage is used to automatically call a function with the required arguments, where arguments come from a pre-defined attribute set. It is defined with callPackageWith, which is defined in here:

I am guessing /root/ethercalc/default.nix is this file:

# This file has been generated by node2nix 1.9.0. Do not edit!

{pkgs ? import <nixpkgs> {
    inherit system;
  }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:

  nodeEnv = import ./node-env.nix {
    inherit (pkgs) stdenv lib python2 runCommand writeTextFile writeShellScript;
    inherit pkgs nodejs;
    libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
import ./node-packages.nix {
  inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit;
  inherit nodeEnv;

If so, it is a function where all its parameters are optional. So, calling it with an empty attribute set like this import /root/ethercalc {} will make its parameters use their default values:

But if you use callPackage to call the function, it will define the parameters to their values from Nixpkgs (pkgs.<parameter-name>) if such an attribute exists in Nixpkgs. So, in this case callPackage /root/ethercalc {} is equivalent to: import /root/ethercalc { inherit (pkgs) pkgs system nodejs; }

More specifically the difference is probably because of the pkgs.nodejs coming from your system is different from the default value of the parameter, which is pkgs.nodejs-12_x.

Oh wow, awesome, thank you so much for your quick and insightful reply! Now everything makes sense.

Thank you! As a direct result of your comment, I was able to create two pull requests (just fyi):

1 Like