Type-graphql: Cannot use GraphQLSchema from another module or realm

Created on 3 Sep 2018  Β·  28Comments  Β·  Source: MichalLytek/type-graphql

Describe the bug
I installed express-graphql and typed-graphql, then I defined my entities and built the schema, when I pass the Schema to express-graphql and added it to my express app. As soon as I open grahpiql in my browser and run a query I get the error:


{
  "errors": [
    {
      "message": "Cannot use GraphQLSchema \"[object Object]\" from another module or realm.\n\nEnsure that there is only one instance of \"graphql\" in the node_modules\ndirectory. If different versions of \"graphql\" are the dependencies of other\nrelied on modules, use \"resolutions\" to ensure only one version is installed.\n\nhttps://yarnpkg.com/en/docs/selective-version-resolutions\n\nDuplicate \"graphql\" modules cannot be used at the same time since different\nversions may have different capabilities and behavior. The data from one\nversion used in the function from another could produce confusing and\nspurious results."
    }
  ]
}

Enviorment (please complete the following information):

  • OS: Ubuntu 18.04
  • Node 10.9.0
  • Package version 0.13.1
  • TypeScript version 3.0.1
Community Discussion Question Solved

Most helpful comment

I got it to work, by explicitly specifying the same version in my package.json as needed by type-graphql. I also had to delete my node_modules and package-lock.json to make npm dedupe the graphql dependency.

But I guess it would be better if type-graphql would specify graphql as peerDependency, to prevent such problems.

All 28 comments

I got it to work, by explicitly specifying the same version in my package.json as needed by type-graphql. I also had to delete my node_modules and package-lock.json to make npm dedupe the graphql dependency.

But I guess it would be better if type-graphql would specify graphql as peerDependency, to prevent such problems.

But I guess it would be better if type-graphql would specify graphql as peerDependency, to prevent such problems.

It's not so simple. The main problem is that TypeGraphQL is tightly coupled to the version of graphql-js, so do the produced schema is. So I can't just put a wildcard ^0.12 || ^0.13 || >=14.0.
If I make it a peerDependency, you still might have incompatibilities between TypeGraphQL and ecosystem, like 0.13 vs 14.0. Also it's error prone as you need to remember to install it too, even if you're not using graphql-js directly anywhere in your code.

So I can't just put a wildcard ^0.12 || ^0.13 || >=14.0.

So don't. Just specify the versions you know are compatible at the time of writing. Everyone does it like this. If a new version comes and it is compatible, you can add it later.

Also it's error prone as you need to remember to install it too, even if you're not using graphql-js directly anywhere in your code.

I think you need to use it always-even apollo-server-core expects it at as peer dep.

Error: Cannot find module 'graphql'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/capaj/git_projects/graphql-repos/ts-gql-objection-blog/node_modules/apollo-server-core/dist/runQuery.js:3:19)

running an apollo server without graphql installed.
To make it easier just put it in the readme.md. Everyone does it like that. Will open a PR.

It's not that simple. I even asked Lee Byron for that:
https://medium.com/@leeb/presumably-if-youre-completely-hiding-away-the-graphql-js-api-then-your-users-will-not-be-using-97e1a683bc93

And that's what TypeGraphQL does - it's hidding graphql-js API with classes and decorators.

@capaj Could you tell me what will happen when I bump the type-graphql version with bumping peerDependency version? Will it automatically update it too or users will have strange errors due to incorrect version of graphql-js?

@19majkel94 I think npm exits with a warning telling them they have a mismatched peerDependency. Like for @marciobueno1 : https://github.com/apollographql/apollo-server/issues/291#issuecomment-277161146

You are hiding it away, but apollo doesn't. Apollo-server uses graphql as peer dependency. Which GraphQL server are we supposed to use? Even if there was one with graphql as a dependency it would still cause these issues with another realm.
I think it's simple. There's really no drawback to having it as peerDependency.

@capaj It's not an error, only a warning, so it's easy to miss when you have other libs in project, like:

PS D:\Gorrion\Projekty\nurture agency\pagebox-react> npm i
npm WARN [email protected] requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of react-dom@^15.4.2 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of react-scripts@^1.0.14 but none is installed. You must install peer dependencies yourself.

audited 32315 packages in 38.785s
found 0 vulnerabilities

PS D:\Gorrion\Projekty\nurture agency\pagebox-react>

So assuming graphql should be a peerDependency, @types/graphql should be too? What about @types/node?

There's really no drawback to having it as peerDependency.

No, there are many:

  • it's more complicated to install (not only type-graphql but also graphql and @types-graphql
  • there's no way to force the update ofgraphql-js to specific version like now I can
  • it still doesn't solve the problem of missmatch version when other lib from the graphql ecosystem use different major version

If all ecosystem libraries have all the same semver setup, the only thing you have to do is call npm dedupe to flatten the deps to a single graphql-js instance in node_modules. I think it's simpler than forcing ALL users to install also graphql and @types/graphql and remember to keep them in sync on updates.

If all ecosystem libraries have all the same semver setup

that's a very big if. Mostly package authors specify their deps quite specific, so it might be impossible to get version of packages which require the right versions of graphql. I agree it's the same thing with peerDeps, but in my experience people specify peerDeps much more broadly than deps.

You're definately right about npm-it only warns which is a shame.

I agree it's the same thing with peerDeps, but in my experience people specify peerDeps much more broadly than deps.

I noticed the same thing and it is plausible too. If I have a dependency it is automatically installed, so usually I would specify a single (mostly the newest) version, but if I have a peer dependency I specify all versions it would work with.

Peer dependencies makes sense for things like plugins, e.g. https://github.com/19majkel94/class-transformer-validator. class-validator could be a peer dependency of TypeGraphQL too, because it only call validate() with validation option, so it doesn't change too much.

But with TypeGraphQL is really tightly coupled to graphql-js - I rely on so many things, API and behaviors. So I need to specify it's version very narrow, for example when new minor version comes out and I need to use the introduced feature.

Many packages from ecosystem, like graphql-query-complexity or even apollo-server only use the schema and call the execute function, so they can have this peer dependency set much more broadly than deps. So upgrading graphql-js version as peer dependency for graphql is a challange. I think that better is to document npm dedupe in docs rather than forcing everybody to install graphql and take care about updates.

Apollo-server uses graphql as peer dependency.

The simple fact that apollo-server use graphql as a peer dependency make impossible to use type-graphql to configure it (with the option param schema: GraphQLSchema) because GraphQLSchema returned by TypeGraphQL.buildSchema is out of date compare to GraphQLSchemaused with apollo-server.

So you are building a GraphQLSchema that will never be usable by other module using latest graphql version. Let the devs configure what version of graphql they want to use is for me the better option.

Edit: type-graphql doesn't broke with graphql-js version 14.x.x

The simple fact that apollo-server use graphql as a peer dependency make impossible to use type-graphql to configure it (with the option param schema: GraphQLSchema) because GraphQLSchema returned by TypeGraphQL.buildSchema is out of date compare to GraphQLSchemaused with apollo-server.

The simple fact means that npm during install of apollo-server will not install new graphql module but just use the one bundled with type-graphql πŸ˜‰

To demonstrate how npm is deduplicating packages - tak a look at graphql-yoga that has graphql defined as a dependency, which is much stronger than peer dependencies:
https://github.com/prisma/graphql-yoga/blob/1dd9c12c166067eeeac8f28de0525dfbb6dc010f/package.json#L48
So graphql-yoga has own graphql package defined, so has type-graphql - but suddenly they work together without any problem as npm reuse the graphql module when they have common semver set up.

So basically this comes down to this dilemma:

  • run npm dedupe when you have GraphQLSchema conflict (only by some people)
  • run npm i graphql on install and npm upgrade graphql or npm i graphql@latest when type-graphql bumps the package version requirement (by everybody)

I think that in this situation it's better to cure with dedupe than preventing with peer dependency πŸ˜‰

So this package is meant to work with graphql yoga out of the box only ?

Your package work with [email protected] the major version, you should at least bump the version in your dependencies to ^14.x.x || ^0.13.x

Edit: npm dedupe don't fix the problem by the way

See #140 - it's a major release with breaking changes, so it does't work with with 14.x.x.

And no, it works with other packages too. The type error that you receive:

[ts]
Argument of type '{ schema: GraphQLSchema; }' is not assignable to parameter of type 'Config & { cors?: boolean | CorsOptions | undefined; }'.
  Type '{ schema: GraphQLSchema; }' is not assignable to type 'Config'.
    Types of property 'schema' are incompatible.
      Type 'import("e:/#Programowanie/#GitHub/apollo-type-graphql/node_modules/type-graphql/node_modules/@types/graphql/type/schema").GraphQLSchema' is not assignable to type 'import("e:/#Programowanie/#GitHub/apollo-type-graphql/node_modules/@types/graphql/type/schema").GraphQLSchema'.
        Types of property 'astNode' are incompatible.
          Type 'Maybe<SchemaDefinitionNode>' is not assignable to type 'SchemaDefinitionNode | undefined'.
            Type 'null' is not assignable to type 'SchemaDefinitionNode | undefined'.

Comes from apollo-link that is a part of apollo-server:

"apollo-link": {
  "version": "1.2.2",
  "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.2.tgz",
  "integrity": "sha512-Uk/BC09dm61DZRDSu52nGq0nFhq7mcBPTjy5EEH1eunJndtCaNXQhQz/BjkI2NdrfGI+B+i5he6YSoRBhYizdw==",
  "requires": {
    "@types/graphql": "0.12.6",
    "apollo-utilities": "^1.0.0",
    "zen-observable-ts": "^0.8.9"
  }
},

As you can see, 0.12.6 is not compatible with ^0.13.4 defined by type-graphql. So as apollo-server version took precedence over type-graphql one, all you need is npm i @types/[email protected]. Here is a gist that you can clone, install and run πŸ˜‰
https://gist.github.com/19majkel94/8f502b2c5de418695d33c675c9c64726

Peer dependency on type-graphql side won't fix the error with two incompatible version of the package, they would still use their own version to define types. Just like the newest apollo-server would be designed for v14, and type-graphql is for 0.13 - they won't work, you have to downgrade apollo-server to earlier version until type-graphql 0.15 comes live πŸ˜‰

apollo-server 2.1.0 has been released, now everything works out of the box with type-graphql 0.14.0 πŸ˜‰

However there's still an error with graphql-yoga that hasn't been upgraded to v14.
Switching to peerDependency wouldn't help in that case as type-graphql 0.15 would demand v14.0.

As Lee Byron said:

Presumably if you’re completely hiding away the graphql-js API, then your users will not be using graphql-js in any other way so it’s probably safe to continue to use a normal dependency. peerDependencies is useful when the peer package is used directly by many others in an ecosystem of software, which is typically true for GraphQL.js

I will come back later to this discussion, depending on how the ecosystem packages will behave. Maybe a section in FAQ about Cannot use GraphQLSchema and GraphQLSchema is not assignable to type errors will prevent this kind of issues πŸ˜‰

I got it to work by removing node_modules/type-graphql/node_modules/graphql, but this isn't really feasible in a production environment. Helps unblock local development until all maintainers get onboard with GQL 14

package.json

{
  "scripts": {
    "postinstall": "rm -rf node_modules/{type-graphql}/node_modules/{@types/graphql,graphql}"
  }
}

@caseyduquettesc Is a temporal Solution, it works for me.

Temporal messy solution for me:

on package.json

"resolutions":{
    "type-graphql/graphql": "^14.0.2"
  },

yarn install

To make it a bit clear for newcomers that are looking for a solution in this issue - there's a little guide in FAQ for this problem:
https://19majkel94.github.io/type-graphql/docs/faq.html#i-got-error-like-cannot-use-graphqlschema-object-object-from-another-module-or-realm-how-to-fix-that

Don't know what's happening I have this same problem and only 1 version of graphql resulting from npm ls graphql

It's even weirder if I tell you it works for the first request and starts having Error: Cannot use GraphQLSchema "[object GraphQLSchema]" from another module or realm. from the second request.

@ramonpm TypeGraphQL now comes with graphql-js as a peer dependency so it's not a source of problem anymore.

@19majkel94 could you please suggest me some way to identify the problem?

fixed now. What helped me was update serverless cli npm update -g serverless.

I ran into another circumstance which caused this error due to symlinking. I'm using a (kind of) fork of Lerna to manage a project such that my project ended up being structured like this:

my_project_package_1
└───node_modules
β”‚   └─── type-graphql
β”‚   β”‚   β”‚   ...
β”‚   └─── graphql
β”‚   β”‚   β”‚   ...
β”‚   └───my_project_package_2
β”‚       └─── node_modules
β”‚       β”‚   └─── graphql --> ../../graphql/
β”‚       β”‚   ...
β”‚   ...

even though there is only one actual copy of the graphql library on disk, the module is being loaded by node twice, once when type-graphql requires graphql and another time when my_project_package_2 requires graphql, because I guess node looks at the path when determining whether a module has been loaded before or not. Since the module is loaded twice the instanceOf check in graphql js fails.

My solution here will be to rewrite a portion of how my Lerna fork works. RIP.

To make it a bit clear for newcomers that are looking for a solution in this issue - there's a little guide in FAQ for this problem:
https://19majkel94.github.io/type-graphql/docs/faq.html#i-got-error-like-cannot-use-graphqlschema-object-object-from-another-module-or-realm-how-to-fix-that

404 😞

@manavm1990
https://typegraphql.com/docs/faq.html#how-do-i-fix-this-error-cannot-use-graphqlschema-object-object-from-another-module-or-realm

I switched from npm to yarn (deleting 'node_modules' and 'package-lock.json' and 'rebuilding') and then added this to 'package.json':

"resolutions": {
    "graphql": "^15.3.0"
  }

It's all working again! 😌

In my case, realized I was using graphql v15.x.x in my application package.json while graphql-yoga was using graphql v14.x.x. Deleted the v15.x.x and replaced it with v14.x.x works. That created a single graphql v14.x.x to be used.

Hope this helps.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

reilem picture reilem  Β·  3Comments

MichalLytek picture MichalLytek  Β·  4Comments

MichalLytek picture MichalLytek  Β·  3Comments

Janushan picture Janushan  Β·  3Comments

Asim13se picture Asim13se  Β·  3Comments