If you have a dependency which has a transitive dependency that points to a GitHub URL, then Yarn and NPM will successfully install it, but yarn2nix will fail with an SSL error when trying to fetch that transitive dependency.
For example, the npm-license-crawler package relies a fork of license-checker which points at a GitHub URL. This dependency list in package.json fails:
However, you can work around this issue by adding the transitive dependency directly into the package.json file. Doing this does cause small changes in the generated lock file, namely that the .git extension is trimmed from the key and resolved url for the license-checker package, which may be all that's needed to work correctly.
You can exactly reproduce this error with the below package.json file, default.nix file, and the yarn executable in a shell so you can generate the yarn.lock file by running yarn.
Attempting to build this tiny project will fail with an SSL certificate problem:
λ nix-build --keep-failed --show-trace
these derivations will be built:
/nix/store/r3qg57qxjpqm607xs83cx4mvd78w1bpv-my-yarn-package-modules-1.0.0.drv
/nix/store/ybn6lc6l2l75r899slq8p10b06q6dvvm-my-yarn-package.drv
...
[1/4] Resolving packages...
error Command failed.
Exit code: 128
Command: git
Arguments: ls-remote --tags --heads https://github.com/mwittig/license-checker
Directory: /private/var/folders/bs/y8pdflhj6t9c3963clpgfz_m0000gn/T/nix-build-my-yarn-package-modules-1.0.0.drv-4
Output:
fatal: unable to access 'https://github.com/mwittig/license-checker/': SSL certificate problem: unable to get local issuer certificate
So the git command fails with an SSL certificate problem when attempting to access a remote URL, namely the mwittig/license-checker repository. This dependency is not listed in the package.json, but it’s a transitive dependency of npm-license-crawler, which we can see in the yarn.lock file:
Fix 1: Add the transitive dependency to package.json
The first thing I noticed is that it’s a little strange npm-license-crawler sees the license-checker dependency at this URL, which does not include the .git extension:
I tried putting these URLs directly into the package.json file to see which one causes the problem, and found to my surprise that putting either URL into the package.json file will change the resulting yarn.lock file and will cause the Nix build to succeed.
First, the diff of putting the URL that npm-license-crawler wants, which has no extension:
This removes the .git extension on the resolved URL and the fetch now succeeds; that makes sense, because the URL I manually provided in the package.json didn’t include it either, and because npm-license-crawler listed this key as the resolver for the license-checker dependency. Maybe now a lookup is succeeding.
What about including the extension in the package.json file, which is how license-checker resolves in the broken version?
This leaves the old entry for license-checker in place, with the .git extension, and it also adds a new entry for license-checker without the .git extension. This nix-build also succeeds!
Moral of the story so far: so long as you put the GitHub dependency directly in the package.json file, with or without a .git extension, the lock file will generate a key and resolved url which does not include the .git extension and which succeeds with yarn2nix. So one (possible) solution to this is to take any failing GitHub transitive dependency and add it directly to the package.json file.
Failed Fix 2: Provide certificates to Yarn when fetching
Ideally this would just work without adding the transitive dependency to the package.json file, so I wanted to check on this SSL error. If I run nix-build --keep-failed then I can see the build at the moment it failed.
One thing stood out to me: the build is explicitly unsetting the SSL_CERT_FILE environment variable,.
I chased this for a bit, providing pkgs.cacert to Yarn as a build init in an overlay, and that got me farther, but the process just hangs at “fetching packages…”. I didn’t dig any further as I suspect this issue is falling out of the prior information I’ve demonstrated.
Short summary
If you have a dependency which has a transitive dependency that points to a GitHub URL, then Yarn and NPM will successfully install it, but yarn2nix will fail with an SSL error when trying to fetch that transitive dependency.
For example, the
npm-license-crawler
package relies a fork oflicense-checker
which points at a GitHub URL. This dependency list inpackage.json
fails:However, you can work around this issue by adding the transitive dependency directly into the
package.json
file. Doing this does cause small changes in the generated lock file, namely that the.git
extension is trimmed from the key and resolved url for thelicense-checker
package, which may be all that's needed to work correctly.Therefore this dependency list works:
Full reproduction + steps taken to fix
You can exactly reproduce this error with the below
package.json
file,default.nix
file, and theyarn
executable in a shell so you can generate theyarn.lock
file by runningyarn
.Attempting to build this tiny project will fail with an SSL certificate problem:
So the
git
command fails with an SSL certificate problem when attempting to access a remote URL, namely themwittig/license-checker
repository. This dependency is not listed in the package.json, but it’s a transitive dependency ofnpm-license-crawler
, which we can see in the yarn.lock file:Fix 1: Add the transitive dependency to package.json
The first thing I noticed is that it’s a little strange
npm-license-crawler
sees thelicense-checker
dependency at this URL, which does not include the.git
extension:But that
license-checker
lists itself at this url, which does include the.git
extension:I tried putting these URLs directly into the
package.json
file to see which one causes the problem, and found to my surprise that putting either URL into thepackage.json
file will change the resultingyarn.lock
file and will cause the Nix build to succeed.First, the diff of putting the URL that
npm-license-crawler
wants, which has no extension:This removes the
.git
extension on the resolved URL and the fetch now succeeds; that makes sense, because the URL I manually provided in thepackage.json
didn’t include it either, and becausenpm-license-crawler
listed this key as the resolver for thelicense-checker
dependency. Maybe now a lookup is succeeding.What about including the extension in the package.json file, which is how
license-checker
resolves in the broken version?This leaves the old entry for
license-checker
in place, with the.git
extension, and it also adds a new entry forlicense-checker
without the.git
extension. This nix-build also succeeds!Moral of the story so far: so long as you put the GitHub dependency directly in the package.json file, with or without a .git extension, the lock file will generate a key and resolved url which does not include the
.git
extension and which succeeds with yarn2nix. So one (possible) solution to this is to take any failing GitHub transitive dependency and add it directly to thepackage.json
file.Failed Fix 2: Provide certificates to Yarn when fetching
Ideally this would just work without adding the transitive dependency to the
package.json
file, so I wanted to check on this SSL error. If I runnix-build --keep-failed
then I can see the build at the moment it failed.One thing stood out to me: the build is explicitly unsetting the SSL_CERT_FILE environment variable,.
I chased this for a bit, providing
pkgs.cacert
to Yarn as a build init in an overlay, and that got me farther, but the process just hangs at “fetching packages…”. I didn’t dig any further as I suspect this issue is falling out of the prior information I’ve demonstrated.