-
-
Notifications
You must be signed in to change notification settings - Fork 676
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
Getting "Schema must contain uniquely named types but contains multiple types named" for a single type #396
Comments
You can't extend a resolver's class without providing different queries/mutation names in a factory function or without making the base resolver |
Hi, not sure what you mean, the BaseResolver class looks like this :
It does not have the |
Oh, I see it's BTW, it's better to inject a base service rather that extending a class to have access to common methods. |
I would rather inject common methods, but then I would have to send the name of the model as a parameter, right now my BaseResolver has acess to the names of the model: export default abstract class DefaultResolver {
abstract get name (): string;
abstract get plural (): string;
protected get model() {
return models[this.name];
}
async fetch(args, info) {
const {filter} = args;
const shouldCount = info.fieldNodes[0].selectionSet.selections.map(s => s.name.value).includes('count');
const filters = filterPipe(filter);
const data = await this.model.find(filters, null, skipLimitPipe(args));
const count = shouldCount ? await countModel(this.model, filters) : -1;
return {[this.plural]: data, count};
}
async fetchAll() {
return this.model.find();
}
async fetchOne(id: string) {
return this.model.findOne({ _id: id });
}
} |
I found one way to produce this bug. Took me a long time to figure out! If you import a file from 2 other files but you type its path with 2 different casings, the TypeScript compiler will include 2 copies of the module in the transpiled JS. This causes any types to be registered multiple times. For example:
Of course, the import statements should match the casing of the actual file. But the macOS filesystem is not case sensitive so it recognizes the file even when the import statement has the wrong casing. There is the compiler option forceConsistentCasingInFileNames that detects bugs like this. Strangely it's turned off by default. @gotenxds Was this also the cause in your case? |
Closing for a housekeeping purposes 🔒 |
I'm struggling with this issue too. Would love to know how you solved it. Unfortunately @AdamDanielKing's solution didn't work, all import statements have consistent casing 😬 |
@jonlambert Would you be able to put together a minimal project that demonstrates the issue, so others can take a look? |
Sure, I'll strip back the project I'm working on as soon as possible. It's a NestJS project, so let me know if you think the issue might be better raised there. |
This was a hard one to track down, with an annoying fix (Nest specific, not the fault of type-graphql). For anyone experiencing the same issue make sure to delete |
I have the same issue and I have it very bounded:
Resolver definition:
So all of it works perfectly until I add the The main tutorial I've been following to get to this issue is https://github.com/benawad/type-graphql-series but I don't find any reason for this problem. Any idea? |
I think you have a similar problem to mine and @jonlambert's. The reason it manifests when you add Your code runs for me. Are you sure there isn't another file where you're importing |
I only have another file related with this, an
When I search for any import or any EDIT: |
Here is the tests I've done:
Any idea with this new info? @MichalLytek @AdamDanielKing |
Not sure. Would you be able to publish a minimal repo that reproduces the error? |
Sure. I'm on it. |
@christopher-avila Your ormconfig.js is referencing the TS file for your entity: You should either configure typeorm from a TS file or use the "dist/" path to the JS files:
This fixes the problem. 🙂 |
I can't believe it. The simplest thing in the simplest file in the whole project. Thank you so much for your time. Solved, right! Thank you! |
Thank you @AdamDanielKing I have been struggling with a casing mismatch for the past couple of hours. Fixed the issue I was having. |
For anyone who is struggling with this issue and tried above recipes with no luck: try to implicitly give a name to your types. My issue was solved with following
Note an arg that was passed to ObjectType |
For the record, I have this issue using Zeit now CLI tool. My GraphQL server is a lambda. First type it compiles, it works fine. When I change something in the code, it recompiles, and produce the error (Schema must contain uniquely named types but contains multiple types named...) |
Looks like this is related with Webpack hot reload compatibility: #289 |
@fromi |
@MichalLytek I just tried, and it fixes my issue! Thanks 👍 |
@vlad-elagin thank you a lot |
@MichalLytek I just tried the beta and it worked. But how stable is it? Do you recommend using it? |
@THPubs it's basically a RC, I was grouping breaking changes, soon v0.18 stable will be released 😉 |
@MichalLytek Cool thanks 😀 |
This solved it for me as well @MichalLytek FYI I am using Next.js which comes with hot reloading out of the box. The initial GraphQL query was always fine, but every other query resulted in this error too. |
FYI: Whenever I used "DateTime" as input args, I got |
@rwieruch |
Was using webpack to build, getting the same error on the generated bundle. {
...,
resolve: {
extensions: [".mjs", ".ts", ".tsx", ".js"]
}
} No idea how mjs helps in this though. |
yeah this is the real solution. |
Complete solution in case if class is used as input and output: @ObjectType('DataStruct')
@InputType('DataStructInput')
export class DataStruct { ... } |
In my case I have created result model with decorater @ObjectType("result") for all models so due to conflit in different result model for each schema/resolver type-graphql schema generation pipeline giving error. So make sure fields, @ObjectType(), @inputType() should be unique |
I fixed the issue by changing the paths.
|
I had the same issue because I decorated the same class as
The solution was to explicitly name the objects
|
I'm getting this variation after deployment to Aws lambda:
I'm not sure where to start looking. Any hints? |
From the look of it and for anyone else that comes along, your files are being minified and your class names are being minified to the same character. This then causes a conflict when TypegraphQl tries to infer the name of the graphql type. Adding the name as an argument to ObjectType or InputType as noted above should fix your issue:
|
Thanks @vlad-elagin, this work for my NestJS project |
How did you fix it? I tried all solution, none of them worked for me |
Another way to fix this, if the issue is the type names getting minified is to disable the minification in Webpack. Had the same issue with Nestjs and fixed by adding the following to my Webpack config:
https://webpack.js.org/configuration/optimization/#optimizationminimize |
I have the same problem with NextJs hot reload. In my case the error is I have a file called import { Field, Float, GraphQLISODateTime, Int, ObjectType } from 'type-graphql';
import { WorkShift } from '@generated/type-graphql';
@ObjectType()
export class HoursWorked {
@Field(() => Float)
duration: number;
@Field(() => Float)
breakDuration: number;
@Field(() => Float)
regularHours: number;
@Field(() => Float)
doubletimeHours: number;
@Field(() => Float)
nightHours: number;
@Field(() => Float)
overtimeHours: number;
}
@ObjectType()
export class Timesheet {
@Field(() => HoursWorked)
hoursWorked: HoursWorked;
@Field(() => [WorkShift])
workShifts: WorkShift[];
}
@ObjectType()
export class WorkWeek {
@Field(() => GraphQLISODateTime)
startOfWeek: Date;
@Field(() => GraphQLISODateTime)
endOfWeek: Date;
@Field(() => Int)
year: number;
@Field(() => Int)
weekOfYear: number;
} The only way I am able to remove the error is by putting the schema as global. But then I lose the ability to actually hot reload when I change resolvers...
import { buildSchema, MiddlewareFn } from 'type-graphql';
import { authChecker } from '@ss/auth';
import { GraphQLYogaError } from 'graphql-yoga';
import { GraphQLSchema } from 'graphql';
import { isDev, isProd } from '@ss/environment';
import { resolvers } from '..';
export const ErrorInterceptor: MiddlewareFn<unknown> = async (_, next) => {
try {
return await next();
} catch (err) {
throw new GraphQLYogaError(err as unknown as string);
}
};
declare global {
// eslint-disable-next-line no-var
var graphQLSchema: GraphQLSchema | undefined;
}
export const createSchema = async () => {
if (global.graphQLSchema) {
return global.graphQLSchema;
}
const schema = await buildSchema({
resolvers: [...resolvers],
authChecker,
validate: false,
emitSchemaFile: isDev(),
dateScalarMode: 'isoDate',
globalMiddlewares: [ErrorInterceptor]
});
if (!isProd()) {
global.graphQLSchema = schema;
}
return schema;
}; I have been at it for countless hours it is driving me insane! |
change to
and potentially disable webpack minimization
|
why is this closed? running into this error is a complete blocker. I am also hitting when using nextJS. Seems to only be a problem with hot reload. What is the fix? this has not effect.
minimize is false by default in development. |
Having the same issue when using multiple prisma schemas: |
using the global trick
that @srosato mentioned above will fix the problem @valerii15298. however this breaks hot reloading in nextjs, which is a huge hit to DX. is there a better way? @MichalLytek |
For my case Don't put multiple |
This worked for me. |
In my situation, I change a ts file name, and don't clean dist before another tsc build, so there are two same type in these two files with different filename in dist. |
Hello, I have the following schema:
From this I generate a schema like this:
And I get the error:
The text was updated successfully, but these errors were encountered: