Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Ensure that there are not multiple versions of GraphQL installed in your node_modules directory #594

Closed
richburdon opened this issue Nov 18, 2016 · 27 comments

Comments

@richburdon
Copy link

[Related to https://github.com/graphql/graphiql/issues/58]

I have two node modules A => B, where B creates a GraphQLSchema object that is imported by A, which is then used to instantiate graphqlExpress.

I get this error:
Ensure that there are not multiple versions of GraphQL installed in your node_modules directory

And see that I have 2 different instances of the GraphQLSchema class type at runtime -- so validate.js invariant(schema instanceof GraphQLSchema) fails because the imported schema is an instance of A's GraphQLSchema not B's GraphQLSchema.

However, all npm dependencies are of the same version (in both A and B modules).

> npm --version
3.10.7

> babel-node --version
6.16.0

> find node_modules -name graphql
node_modules/graphql
node_modules/graphql-subscriptions/node_modules/graphql

> grep version node_modules/graphql/package.json 
0.7.2

> grep version node_modules/graphql-subscriptions/node_modules/graphql/package.json
0.7.2

I assume this is a common pattern, but I can't find an example.

BTW, I'm using npm-link to create the A => B dependency.

@richburdon
Copy link
Author

Using peerDependencies in A/package.json I managed to get rid of node_modules/graphql-subscriptions/node_modules/graphql:

  "peerDependencies": {
    "graphql": "^0.7.0",
    "graphql-subscriptions": "^0.2.1"
  }

But the problem remains since A's GraphQLSchema class is different from B's.

@stubailo
Copy link
Contributor

This seems like a problem with npm or possibly the graphql-subscriptions package, not with graphql-js.

@richburdon
Copy link
Author

Probably right, but this seemed like a common pattern?

@stubailo
Copy link
Contributor

Sure, I guess I'm just saying there isn't much graphql-js can do about this. It's a good thing that it checks that you only have one instance, otherwise there would be much worse problems.

@richburdon
Copy link
Author

I think this is the solution (if you're using webpack):

  resolve: {
    alias: {
      graphql:  path.resolve('./node_modules/graphql'),
      react:    path.resolve('./node_modules/react')                // Same issue.
    }
  }

http://stackoverflow.com/questions/31169760/how-to-avoid-react-loading-twice-with-webpack-when-developing

@casoetan
Copy link

casoetan commented Apr 14, 2017

Got this issue as well.

Using node 7.9

$ find node_modules -name graphql

node_modules/@types/graphql
node_modules/graphql

should i just delete the @types/graphql directory?

I don't think this should affect it but...

@wincent
Copy link
Contributor

wincent commented Apr 17, 2017

@casoetan: deleting it sounds like a reasonable bet.

@jay-jlm
Copy link

jay-jlm commented Apr 17, 2017

I get the same results of casoetan.
deleting @types/graphql doesnt seem to have an effect

@casoetan
Copy link

The issue seems to be the way i called makeExecutableSchema. Solved this by using 'graphql-modules'.

@richburdon
Copy link
Author

richburdon commented May 29, 2017

@stubailo I resolved this for webpack some time ago, but the problem still exists for monorepos that have different sub packages referencing modules that depend on graphql.

I tried lerna --hoist to resolve, but this is flaky.

(BTW, I removed the dependency on graphql-subscriptions (red herring).

I've also tried moving graphql deps into peerDependencies for my own sub packages that my failing package depends on.

In the module where the error occurs (as above):

find -L node_modules -name graphql
node_modules/@types/graphql
node_modules/test-api/node_modules/@types/graphql
node_modules/test-api/node_modules/test-core/node_modules/@types/graphql
node_modules/test-api/node_modules/test-core/node_modules/graphql
node_modules/test-client/node_modules/@types/graphql
node_modules/test-client/node_modules/test-api/node_modules/@types/graphql
node_modules/test-client/node_modules/test-api/node_modules/test-core/node_modules/@types/graphql
node_modules/test-client/node_modules/test-api/node_modules/test-core/node_modules/graphql
node_modules/test-client/node_modules/test-core/node_modules/@types/graphql
node_modules/test-client/node_modules/test-core/node_modules/graphql
node_modules/test-client/node_modules/graphql
node_modules/test-core/node_modules/@types/graphql
node_modules/test-core/node_modules/graphql
node_modules/graphql

where test-* are linked modules (all of which define graphql as peerDependencies.

I assume @types/graphql are normal TypeScript deps?

@richburdon richburdon reopened this May 29, 2017
@leebyron
Copy link
Contributor

Closing this aging issue.

graphql-js is not designed to support using functionality between different installations of itself. The instanceof is only one example where this failure occurs - but there are others as well, especially if there would ever be inadvertent differences in released versions.

If you use packages with sub-packages, ensure they support ranges of versions for graphql so that npm or yarn can find a single version to install at the top level which works for all dependents.

@leebyron
Copy link
Contributor

A note for those still encountering this issue, yarn is pretty good at doing this version resolution, including support for a flag which enforces guarantees for a single version of every dependency if you want that. I believe npm5 also has some support for this kind of guarantee

@webmobiles
Copy link

I'm using yarn and have the same error

@michaellee8
Copy link

I have also faced this error, for example, my express-graphql uses graphql@11.x.x but I had installed graphql@8.x.x due to graphql-sequelize-crud uses a old version of graphql. I checked this out by this command

$ find node_modules -name graphql
node_modules/express-graphql/node_modules/graphql
node_modules/graphql

So I just run rm -rf node_modules/express-graphql/node_modules/graphql here and everything solved.
Note that basically you need to only have 1 line result for find node_modules -name graphql

@jdachtera
Copy link

I'm facing this problem today using yarn. I believe the source of this is that graphql-js is still using alpha versions (0.x...) and therefore the normal semver ranges don't apply. So #1005 needs to be fixed.

@nishant-dani
Copy link

nishant-dani commented Dec 22, 2020

I have only a single instance of graphql in node_modules.

I have a shared GraphQLObject instance that is created in a library and I have resolved that
main: console.log(case 1): graphql path is ${require.resolve('graphql')}) and
library: console.log(case 2): graphql path is ${require.resolve('graphql')}) both resolve to the same path.

Yet I get the instanceof error flagged - that somehow it detects that the GraphQLObject object are belonging to different graphl instances.

@benjie
Copy link
Member

benjie commented Dec 22, 2020

@nishant-dani Do you have a bundler or minifier corrupting the exports?

@thekevinbrown
Copy link

I have the following:

❯ find node_modules -name graphql
node_modules/graphql
❯ yarn list graphql
yarn list v1.22.5
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ graphql@15.4.0
✨  Done in 1.65s.

So there's definitely only one version, and yet:

Error: Cannot use GraphQLSchema "[object GraphQLSchema]" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.

I'm in a typescript monorepo, so there's no bundler or minifier, just the TS compiler. I have no idea what to do to isolate the issue.

@jayeshmann
Copy link

@thekevinbrown I am having the same issue, yours is fixed?

@PatrykMilewski
Copy link

Having the same issue as @thekevinbrown

@benjie
Copy link
Member

benjie commented Sep 24, 2021

One cause of this, other than having duplicate modules, is having graphql imported two different ways - e.g. having it imported as CommonJS in one location and having it imported as ESM in another location. This results in two independent sets of objects in memory and is one potential cause of this error. If you're using a bundler you should be able to have it show you what it's importing - if it's importing both of these files then this is your issue:

@PatrykMilewski
Copy link

In my case enforcing resolution to version 14 instead of 0.13 fixed the issue

@thekevinbrown
Copy link

@PatrykMilewski and @jayeshmann, in our case this was actually caused by Serverless Offline. The fix was, of all things, a configuration option allowCache: true like here: dherault/serverless-offline#931 (comment)

Absent this, Serverless Offline uses a type of threading to run the lambdas, and that's where the duplicates come from. There's also useChildProcesses but that's much slower than simply allowing it to have a require cache properly.

@bombillazo
Copy link

Is there a way to avoid this error even when having multiple installed versions? This is a nightmare to deal with with monorepos and toolings that all install their own version of GraphQL (Nx, Expo, graphql-tools, etc)...

@yaacovCR
Copy link
Contributor

All libraries should install graphql-js as a peer dependency so that a separate version is not installed. If this is not the case for some library, it should be reported as a bug to the library developers.

Otherwise, resolutions can be used with some package managers to force dependencies to use a single version.

Explorations have begun to support multiple packages for cjs/esm support, but you normally should not run into problems. graphql-tools in particular, as far as I am aware, correctly installs this library as a peer.

@benjie
Copy link
Member

benjie commented Jul 20, 2022

All libraries should install graphql-js as a peer dependency so that a separate version is not installed. If this is not the case for some library, it should be reported as a bug to the library developers.

Are you certain this advice works with all package managers (npm, yarn, yarn pnp, pnpm, etc), with nested dependencies which each have a dependence on graphql, and in repositories that use workspaces? Personally I've found yarn pnp to be very picky about peerDependencies in the past, and even in non-pnp mode IIRC peerDependency warnings are output if packageA peerDepends on graphql and also depends on packageB which peerDepends on graphql and you only have graphql at the top level. I may be misremembering though...

@yaacovCR
Copy link
Contributor

I'd certainly be open to learning more from a minimal reproduction of any issue with this approach, simply to further my own knowledge.

But I can't figure how the solution would be inside this library if particular package managers don't respect peer dependencies as peer-only?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests