Skip to content
This repository has been archived by the owner. It is now read-only.

UNMET PEER DEPENDENCY #15708

Open
almadsen opened this Issue Feb 8, 2017 · 22 comments

Comments

Projects
None yet
@almadsen
Copy link

almadsen commented Feb 8, 2017

Hi,
I'm opening this issue because npm is doing something I don't understand.

I get the error message UNMET PEER DEPENDENCY even though I have the said dependency installed.

I'm tying to install eslint-config-airbnb globally and it gives me:

npm install -g eslint-config-airbnb
/usr/local/lib
├── UNMET PEER DEPENDENCY eslint@^3.15.0
├─┬ eslint-config-airbnb@14.1.0
│ ├── UNMET PEER DEPENDENCY eslint@^3.15.0
│ └── UNMET PEER DEPENDENCY eslint-plugin-import@^2.2.0
├── UNMET PEER DEPENDENCY eslint-plugin-import@^2.2.0
├── UNMET PEER DEPENDENCY eslint-plugin-jsx-a11y@^3.0.2 || ^4.0.0
└── UNMET PEER DEPENDENCY eslint-plugin-react@^6.9.0

npm WARN eslint-config-airbnb@14.1.0 requires a peer of eslint@^3.15.0 but none was installed.
npm WARN eslint-config-airbnb@14.1.0 requires a peer of eslint-plugin-jsx-a11y@^3.0.2 || ^4.0.0 but none was installed.
npm WARN eslint-config-airbnb@14.1.0 requires a peer of eslint-plugin-import@^2.2.0 but none was installed.
npm WARN eslint-config-airbnb@14.1.0 requires a peer of eslint-plugin-react@^6.9.0 but none was installed.
npm WARN eslint-config-airbnb-base@11.1.0 requires a peer of eslint@^3.15.0 but none was installed.
npm WARN eslint-config-airbnb-base@11.1.0 requires a peer of eslint-plugin-import@^2.2.0 but none was installed.

I have the all installed, latest, and even tried to uninstall and the reinstall the exact required version, but still get the error.

And this is a quit common problem for me, getting UNMET PEER DEPENDENCY even though I have the said dependency installed.

npm v: 4.1.2
node v: 7.5.0
npm config get registry: https://registry.npmjs.org/
macOS 10.12.3

@alexduan

This comment has been minimized.

Copy link

alexduan commented Feb 10, 2017

I have been receiving similar notices as well with 7.5.0. Switching to an older version of node fixes the issue.

@GoodGuyNick

This comment has been minimized.

Copy link

GoodGuyNick commented Feb 12, 2017

I have same errors but with node v6.9.5

@hell0world

This comment has been minimized.

Copy link

hell0world commented Feb 12, 2017

same here~node v6.9.5

@marhalpert

This comment has been minimized.

Copy link

marhalpert commented Mar 7, 2017

same here~node v6.9.5

I am not installing it globally

@camloken

This comment has been minimized.

Copy link

camloken commented May 12, 2017

Same issue here running node 7.2.0

@RandyRomero

This comment has been minimized.

Copy link

RandyRomero commented Jun 16, 2017

Same here on two different machines with eslint 4.0. Node v 8.1.0. And eslint doesn't work. Can't find anything related in Google.

npm ERR! peer dep missing: eslint@^3.19.0, required by eslint-config-airbnb@15.0.1
npm ERR! peer dep missing: eslint@2.x - 3.x, required by eslint-plugin-import@2.3.0
npm ERR! peer dep missing: eslint@^2.10.2 || 3.x, required by eslint-plugin-jsx-a11y@5.0.3
npm ERR! peer dep missing: eslint@^3.19.0, required by eslint-config-airbnb-base@11.2.0

On machine with eslint 3.20 everything is ok.

@ShaunEgan

This comment has been minimized.

Copy link

ShaunEgan commented Jun 27, 2017

I have the same issue with esline@4.0.0, node v6.10.1

@iarna iarna added the bug label Jul 6, 2017

@iarna

This comment has been minimized.

Copy link
Member

iarna commented Jul 6, 2017

Hey, could you all give a try again with npm@5, we fixed a whole slew of issues and I think I fixed this one.

@TodayyadoT

This comment has been minimized.

Copy link

TodayyadoT commented Jul 31, 2017

same here~node v7.4.0

Anyone fixed it?

@daraclare

This comment has been minimized.

Copy link

daraclare commented Jul 31, 2017

@iarna Thanks for your suggestion, I updated to the latest version of npm 5.3.0, uninstalled both eslint and eslint-plugin-import and reinstalled them, and I no longer get the error. Thank you!

@jhermsmeier

This comment has been minimized.

Copy link

jhermsmeier commented Oct 24, 2017

This still appears to be a problem with npm@5;

$ node -v
v8.7.0
$ npm -v
5.5.1
$ npm ls

# ... lines omitted for brevity ...

│   └─┬ yauzl@2.4.1
│     └── fd-slicer@1.0.1 deduped
├─┬ electron-builder@19.9.1
│ ├─┬ 7zip-bin@2.2.7
│ │ ├── UNMET OPTIONAL DEPENDENCY 7zip-bin-linux@^1.1.0
│ │ ├── 7zip-bin-mac@1.0.1
│ │ └── UNMET OPTIONAL DEPENDENCY 7zip-bin-win@^2.1.1
│ ├─┬ UNMET PEER DEPENDENCY ajv@5.2.5
│ │ ├── co@4.6.0
│ │ ├── fast-deep-equal@1.0.0
│ │ ├── json-schema-traverse@0.3.1
│ │ └── json-stable-stringify@1.0.1 deduped
│ ├── ajv-keywords@2.1.0
│ ├─┬ asar-integrity@0.1.1
│ │ ├── bluebird-lst@1.0.5 deduped
│ │ └── fs-extra-p@4.4.4 deduped

# ... lines omitted for brevity ...

npm ERR! peer dep missing: ajv@>=5.0.0, required by ajv-keywords@2.1.0
@JESii

This comment has been minimized.

Copy link

JESii commented Nov 3, 2017

This is the bane of my existence in node -- ruby has bundler and it just works!
node v8.8.0
npm v5.5.1
webpack v3.1.0

If I install the version that's requested, then another "UNMET PEER DEPENDENCY" shows up
npm ls
image

npm install webpack@2.7.0
package.json is updated to this version
but webpack version is still 3.1.0
so I say to myself -- maybe it's the global webpack that's causing the problem so I
npm uninstall -g webpack
BOOM!
image

The rabbit hole just got bigger!

@seila23

This comment has been minimized.

Copy link

seila23 commented Nov 30, 2017

here the solution :
npm install --save-dev eslint eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react

@dzf0023

This comment has been minimized.

Copy link

dzf0023 commented Jan 19, 2018

@seila23 could you please explain your solution more clearly....Thank you

@seila23

This comment has been minimized.

Copy link

seila23 commented Jan 26, 2018

just install 5 library :

  1. eslint
  2. eslint-config-airbnb
  3. eslint-plugin-jsx-a11y
  4. eslint-plugin-import
  5. eslint-plugin-react
@nswarte

This comment has been minimized.

Copy link

nswarte commented Feb 7, 2018

Hi,
I can reproduce the same issue with other dependencies w/ npm 5.6.0 and node 8.9.4.
The unexpected UNMET PEER DEPENDENCY disappears only if the installed packaged version exactly matches the version number in the comparator used for specifying the peer dependency.
For instance:
my package.json:

{
  "name": "peerdeptest",
  "version": "0.0.1",
  "description": "",
  "files": [
    "dist"
  ],
  "author": "nico",
  "license": "UNLICENSED",
  "devDependencies": {
    "typedoc": "0.6.0",
    "typedoc-webpack-plugin": "^1.1.4"
  }
}

and typedoc-webpack-plugin package.json specifies the typedoc peer dependency this way:

"peerDependencies": {
    "typedoc": ">= 0.5.0"
  }

So I'm getting the following errors when doing npm list:

+-- UNMET PEER DEPENDENCY typedoc@0.6.0
| +-- @types/fs-extra@2.1.0
| | `-- @types/node@9.4.1
| +-- @types/handlebars@4.0.36
...
npm ERR! peer dep missing: typedoc@^0.5.0, required by typedoc-webpack-plugin@1.1.4

Even so the peer dependency version is specified using >=0.5.0, a higher installed version (0.6.0) yield to UNMET error.
Now if I change my package.json to specify exactly 0.5.0 as the version to install for typedoc, errors are cleared:

+-- typedoc@0.5.0
| +-- fs-extra@0.30.0
| | +-- graceful-fs@4.1.11
| | +-- jsonfile@2.4.0
...

Hope this could help track down the problem.

@bjornstar

This comment has been minimized.

Copy link

bjornstar commented Feb 16, 2018

I've created a very simple set of packages to reproduce this problem based on real world packages that exhibit this behavior:

https://www.npmjs.com/package/@peer-deps-repro/main

Steps to reproduce

git clone git@github.com:peer-deps-repro/main.git
cd main
npm install

The current major version has this incorrect behavior:

$> node -v
v8.9.4
$> npm -v
5.6.0
$> npm install
npm WARN @peer-deps-repro/dep-e@1.0.0 requires a peer of @peer-deps-repro/dep-d@6.0.0 but none is installed. You must install peer dependencies yourself.

added 6 packages in 1.796s
$> echo $?
0
$> npm ls
@peer-deps-repro/main@1.0.1 /mnt/f/main
├─┬ @peer-deps-repro/dep-a@1.0.0
│ └─┬ @peer-deps-repro/dep-c@1.0.0
│   └── @peer-deps-repro/dep-d@5.0.0
└─┬ @peer-deps-repro/dep-b@3.0.0
  ├── UNMET PEER DEPENDENCY @peer-deps-repro/dep-d@6.0.0
  └── @peer-deps-repro/dep-e@1.0.0

npm ERR! peer dep missing: @peer-deps-repro/dep-d@6.0.0, required by @peer-deps-repro/dep-e@1.0.0
$> echo $?
1
$>

Going back one major version, the install still behaves incorrectly:

$> node -v
v6.10.2
$> npm -v
4.5.0
$> npm install
@peer-deps-repro/main@1.0.1 /mnt/f/main
├─┬ @peer-deps-repro/dep-a@1.0.0
│ └─┬ @peer-deps-repro/dep-c@1.0.0
│   └── @peer-deps-repro/dep-d@5.0.0
└─┬ @peer-deps-repro/dep-b@3.0.0
  └── @peer-deps-repro/dep-e@1.0.0

npm WARN @peer-deps-repro/dep-e@1.0.0 requires a peer of @peer-deps-repro/dep-d@6.0.0 but none was installed.
$> echo $?
0
$> npm ls
@peer-deps-repro/main@1.0.1 /mnt/f/main
├─┬ @peer-deps-repro/dep-a@1.0.0
│ └─┬ @peer-deps-repro/dep-c@1.0.0
│   └── @peer-deps-repro/dep-d@5.0.0
└─┬ @peer-deps-repro/dep-b@3.0.0
  ├── UNMET PEER DEPENDENCY @peer-deps-repro/dep-d@6.0.0
  └── @peer-deps-repro/dep-e@1.0.0

npm ERR! peer dep missing: @peer-deps-repro/dep-d@6.0.0, required by @peer-deps-repro/dep-e@1.0.0
$> echo $?
1
$>

Going back 2 major versions it installs correctly:

$ node -v
v4.8.7
$> npm -v
2.15.11
$> rm -rf node_modules/
$> node -v
v4.8.7
$> npm -v
2.15.11
$> npm install
@peer-deps-repro/dep-b@3.0.0 node_modules/@peer-deps-repro/dep-b
├── @peer-deps-repro/dep-e@1.0.0
└── @peer-deps-repro/dep-d@6.0.0

@peer-deps-repro/dep-a@1.0.0 node_modules/@peer-deps-repro/dep-a
└── @peer-deps-repro/dep-c@1.0.0 (@peer-deps-repro/dep-d@5.0.0)
$> echo $?
0
$> npm ls
@peer-deps-repro/main@1.0.1 /mnt/f/main
├─┬ @peer-deps-repro/dep-a@1.0.0
│ └─┬ @peer-deps-repro/dep-c@1.0.0
│   └── @peer-deps-repro/dep-d@5.0.0
└─┬ @peer-deps-repro/dep-b@3.0.0
  ├── @peer-deps-repro/dep-d@6.0.0
  └── @peer-deps-repro/dep-e@1.0.0

$> echo $?
0
$>
@bjornstar

This comment has been minimized.

Copy link

bjornstar commented Feb 16, 2018

Looking at the file structure, it actually does install correctly, npm just fails to enumerate them properly.

$> find node_modules/
node_modules/
node_modules/@peer-deps-repro
node_modules/@peer-deps-repro/dep-a
node_modules/@peer-deps-repro/dep-a/LICENSE
node_modules/@peer-deps-repro/dep-a/package.json
node_modules/@peer-deps-repro/dep-a/README.md
node_modules/@peer-deps-repro/dep-b
node_modules/@peer-deps-repro/dep-b/LICENSE
node_modules/@peer-deps-repro/dep-b/node_modules
node_modules/@peer-deps-repro/dep-b/node_modules/@peer-deps-repro
node_modules/@peer-deps-repro/dep-b/node_modules/@peer-deps-repro/dep-d
node_modules/@peer-deps-repro/dep-b/node_modules/@peer-deps-repro/dep-d/LICENSE
node_modules/@peer-deps-repro/dep-b/node_modules/@peer-deps-repro/dep-d/package.json
node_modules/@peer-deps-repro/dep-b/node_modules/@peer-deps-repro/dep-d/README.md
node_modules/@peer-deps-repro/dep-b/package.json
node_modules/@peer-deps-repro/dep-b/README.md
node_modules/@peer-deps-repro/dep-c
node_modules/@peer-deps-repro/dep-c/LICENSE
node_modules/@peer-deps-repro/dep-c/package.json
node_modules/@peer-deps-repro/dep-c/README.md
node_modules/@peer-deps-repro/dep-d
node_modules/@peer-deps-repro/dep-d/LICENSE
node_modules/@peer-deps-repro/dep-d/package.json
node_modules/@peer-deps-repro/dep-d/README.md
node_modules/@peer-deps-repro/dep-e
node_modules/@peer-deps-repro/dep-e/LICENSE
node_modules/@peer-deps-repro/dep-e/package.json
node_modules/@peer-deps-repro/dep-e/README.md
$>

Which would explain why apps still function even though npm is spitting out errors and warnings.

@filipesilva

This comment has been minimized.

Copy link

filipesilva commented Feb 23, 2018

@bjornstar Yes I think #19877 is a duplicate of this one.

You said

Looking at the file structure, it actually does install correctly, npm just fails to enumerate them properly.

I don't think that it's installed correctly. I ran your repro steps and it resolves to a toplevel dep-d@5.0.0 alongside dep-e@1.0.0, thus failing the peer dependency.

dep-d@6.0.0 and only be found at inside node_modules/@peer-deps-repro/dep-b/node_modules/, from where dep-e was hoisted out.

Code might work but only because it works with the wrong peerdep regardless. This is still a real peer dependency problem.

When dep-e tries to require dep-d from node_modules, it will get dep-d@5.0.0 instead of dep-b/node_modules/dep-d@6.0.0.

Note: omitted @peer-deps-repro to make it clearer.

@bjornstar

This comment has been minimized.

Copy link

bjornstar commented Feb 24, 2018

it resolves to a toplevel dep-d@5.0.0 alongside dep-e@1.0.0, thus failing the peer dependency.

That's not how node's require works.

dep-b requires dep-d@6.0.0 and dep-e@1.0.0. dep-e@1.0.0 has a peer dependency of dep-d@6.0.0

When dep-e requires dep-d within the context of dep-b it will get dep-d@6.0.0 from the dependencies of dep-b which is the correct behavior, but npm detects this incorrectly.

I've just released 2 new versions of the main repo with some instrumentation to make it more clear:

main@1.1.0

This version has an invalid peer dependency. dep-e@1.1.0 wants dep-d@6.1.0, but dep-b@3.1.0 has required dep-d@5.1.0 which is invalid. npm should fail to install this version with a big error saying invalid peer dependency, but it displays a warning and does not fail at all.

main@1.2.0

This version has all correct dependencies, but npm complains anyway.

The newly instrumented code logs the package name and version when it is required in node. Here's the output showing the correct behavior:

$> node .
@peer-deps-repro/main 1.2.0
@peer-deps-repro/dep-a 1.2.0
@peer-deps-repro/dep-b 3.2.0
@peer-deps-repro/dep-d 6.1.0
@peer-deps-repro/dep-e 1.1.0
@peer-deps-repro/dep-d 5.1.0
@peer-deps-repro/dep-c 1.1.0
$> 

There are multiple problems with the current peer dependency warnings, but the one I want to focus on is the spurious warnings when no problem exists. I think I have a fix for it, but working with this codebase is a bit more work than I anticipated.

diff --git a/lib/install/deps.js b/lib/install/deps.js
index 54cc525..075c9db 100644
--- a/lib/install/deps.js
+++ b/lib/install/deps.js
@@ -683,8 +683,10 @@ var validatePeerDeps = exports.validatePeerDeps = function (tree, onInvalid) {
     try {
       var spec = npa.resolve(pkgname, version)
     } catch (e) {}
-    var match = spec && findRequirement(tree.parent || tree, pkgname, spec)
-    if (!match) onInvalid(tree, pkgname, version)
+    tree.requiredBy.forEach(function (requiredBy) {
+      var match = spec && findRequirement(requiredBy, pkgname, spec)
+      if (!match) onInvalid(tree, pkgname, version)
+    })
   })
 }

This doesn't fix any of the other problems, but it does cause the validator to resolve the dependencies correctly. I'll raise a PR, but I've already spent way too much time making the repro steps to write the tests for it.

@filipesilva

This comment has been minimized.

Copy link

filipesilva commented Feb 24, 2018

@bjornstar I really appreciate you taking the time to explain this to me, as I am not not fully familiar with the resolve internals.

I pulled your repro, updated to v1.2.0 and saw the same output. Below is the output of npm ls:

$ npm ls
@peer-deps-repro/main@1.2.0 D:\sandbox\main
+-- @peer-deps-repro/dep-a@1.2.0
| `-- @peer-deps-repro/dep-c@1.1.0
|   `-- @peer-deps-repro/dep-d@5.1.0
`-- @peer-deps-repro/dep-b@3.2.0
  +-- UNMET PEER DEPENDENCY @peer-deps-repro/dep-d@6.1.0
  `-- @peer-deps-repro/dep-e@1.1.0

npm ERR! peer dep missing: @peer-deps-repro/dep-d@6.1.0, required by @peer-deps-repro/dep-e@1.1.0

And here is my directory structure:

D:\sandbox\main
└── node_modules
|  └── @peer-deps-repro
|     ├── dep-a
|     ├── dep-b
|     |  └── node_modules
|     |  |  └── @peer-deps-repro
|     |  |     └── dep-d
|     ├── dep-c
|     ├── dep-d
|     └── dep-e

Then I went into main.js changed it to show only the dep-b logs:

var pkg = require('./package.json');
console.log(pkg.name, pkg.version);

// require('@peer-deps-repro/dep-a');
require('@peer-deps-repro/dep-b');

I went into node_modules/@peer-deps-reprio/dep-b/index.js and left only the dep-e logs:

var pkg = require('./package.json');
console.log(pkg.name, pkg.version);

// require('@peer-deps-repro/dep-d');
require('@peer-deps-repro/dep-e');

I believe this should print the versions that dep-e is using from within dep-b:

$ node .
@peer-deps-repro/main 1.2.0
@peer-deps-repro/dep-b 3.2.0
@peer-deps-repro/dep-e 1.1.0
@peer-deps-repro/dep-d 5.1.0

You said

When dep-e requires dep-d within the context of dep-b it will get dep-d@6.0.0 from the dependencies of dep-b which is the correct behavior, but npm detects this incorrectly.

But looking at these logs it seems like dep-e@1.1.0, which has a dep-d@6.1.0 peerdep, ends up getting dep-d@5.1.0 thus violating its peerdep. I don't think the that dep-e being imported from within dep-b made any difference, it still got the closest one (./node_modules/dep-d@5.1.0 instead of node_modules/dep-b/node_modules/dep-d@6.1.0).

Am I missing something in this reasoning? I don't mean to be difficult or anything, I just want to confirm we're looking at the same thing and taking the same conclusions.

@bjornstar

This comment has been minimized.

Copy link

bjornstar commented Feb 25, 2018

Aw man, looks like you are right @filipesilva. I guess it was just wishful thinking that npm's peer dependencies implementation wasn't broken for the last 3 years. I was really hoping it was just a validation bug.

I've updated the instrumentation for this repro case to make it clear which module gets which dependency and it's as you said. Here's the output from main@1.3.1 using npm@5.6.0 to install:

$> nvm use 8
Now using node v8.9.4 (npm v5.6.0)
$> rm -rf node_modules && npm install && node .
npm WARN @peer-deps-repro/dep-e@1.2.0 requires a peer of @peer-deps-repro/dep-d@6.2.0 but none is installed. You must install peer dependencies yourself.

added 6 packages in 1.556s
{
  "pkgName": "@peer-deps-repro/main",
  "pkgVersion": "1.3.1",
  "depA": {
    "pkgName": "@peer-deps-repro/dep-a",
    "pkgVersion": "1.3.0",
    "depB": {
      "pkgName": "@peer-deps-repro/dep-b",
      "pkgVersion": "3.3.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "6.2.0"
      },
      "depE": {
        "pkgName": "@peer-deps-repro/dep-e",
        "pkgVersion": "1.2.0",
        "depD": {
          "pkgName": "@peer-deps-repro/dep-d",
          "pkgVersion": "5.2.0"
        }
      }
    },
    "depC": {
      "pkgName": "@peer-deps-repro/dep-c",
      "pkgVersion": "1.2.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "5.2.0"
      }
    }
  },
  "depB": {
    "pkgName": "@peer-deps-repro/dep-b",
    "pkgVersion": "3.3.0",
    "depD": {
      "pkgName": "@peer-deps-repro/dep-d",
      "pkgVersion": "6.2.0"
    },
    "depE": {
      "pkgName": "@peer-deps-repro/dep-e",
      "pkgVersion": "1.2.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "5.2.0"
      }
    }
  }
}
$>

and the same thing using npm@2.15.11

$> nvm use 4
Now using node v4.8.7 (npm v2.15.11)
$> rm -rf node_modules && npm install && node .
@peer-deps-repro/dep-b@3.3.0 node_modules/@peer-deps-repro/dep-b
├── @peer-deps-repro/dep-d@6.2.0
└── @peer-deps-repro/dep-e@1.2.0

@peer-deps-repro/dep-a@1.3.0 node_modules/@peer-deps-repro/dep-a
└── @peer-deps-repro/dep-c@1.2.0 (@peer-deps-repro/dep-d@5.2.0)
{
  "pkgName": "@peer-deps-repro/main",
  "pkgVersion": "1.3.1",
  "depA": {
    "pkgName": "@peer-deps-repro/dep-a",
    "pkgVersion": "1.3.0",
    "depB": {
      "pkgName": "@peer-deps-repro/dep-b",
      "pkgVersion": "3.3.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "6.2.0"
      },
      "depE": {
        "pkgName": "@peer-deps-repro/dep-e",
        "pkgVersion": "1.2.0",
        "depD": {
          "pkgName": "@peer-deps-repro/dep-d",
          "pkgVersion": "6.2.0"
        }
      }
    },
    "depC": {
      "pkgName": "@peer-deps-repro/dep-c",
      "pkgVersion": "1.2.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "5.2.0"
      }
    }
  },
  "depB": {
    "pkgName": "@peer-deps-repro/dep-b",
    "pkgVersion": "3.3.0",
    "depD": {
      "pkgName": "@peer-deps-repro/dep-d",
      "pkgVersion": "6.2.0"
    },
    "depE": {
      "pkgName": "@peer-deps-repro/dep-e",
      "pkgVersion": "1.2.0",
      "depD": {
        "pkgName": "@peer-deps-repro/dep-d",
        "pkgVersion": "6.2.0"
      }
    }
  }
}
$>

In all actuality, I think we should be able to remove peer dependencies since we are deduping now. I'll go ahead and close my PR as it doesn't fix anything.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.