graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Regression in 10.0.19: Error: Cannot determine a GraphQL input type ("....") for the "...". Make sure your class is decorated with an appropriate decorator. at InputTypeFactory.create

Open andreialecu opened this issue 3 years ago • 8 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current behavior

After upgrading to 10.0.22 I started getting a weird error about in a pretty big project:

Error: Cannot determine a GraphQL input type ("ClubModel") for the "club". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create

There was no context as to where this error originated, so I had to add various console.logs inside @nestjs/graphql to find it.

I eventually tracked it down to this piece of code:

image

The error was about an InputType being expected on a @ResolveField() so this is very bizarre.

Here's the relevant code:

const isAbstract = getAppCaller() === AppCaller.PublicApi ? true : false;

function resolveType(value: { kind: typeof ALL_CLOCK_UNIT_KINDS[number] }) {
  return ALL_CLOCK_UNIT_MODELS.find((c) => c.kind === value.kind);
}

@InterfaceType("ClockDeviceUnit", {
  isAbstract,
  resolveType,
})
@InputType("ClockDeviceUnitBaseInput", { isAbstract })
export class ClockDeviceUnitBaseModel {
  @prop({ type: () => String, required: true })
  kind!: ClockDeviceUnitKinds;

  @prop({ required: true })
  @Field()
  clubId!: string;
}

@Resolver(() => ClockDeviceUnitBaseModel)
export class ClockDeviceUnitResolver {
  constructor(private readonly clubService: ClubsService) {}

  @ResolveField(() => ClubModel)
  async club(@Parent() unit: ClockDeviceUnitBaseModel): Promise<ClubModel> {
    return this.clubService.getClub(unit.clubId);
  }
}

Minimum reproduction code

nope

Steps to reproduce

No response

Expected behavior

A @ResolveField() should not participate in inputs, I suspect a refactoring broke this.

Package version

10.0.19

Graphql version

No response

NestJS version

No response

Node.js version

No response

In which operating systems have you tested?

  • [X] macOS
  • [ ] Windows
  • [ ] Linux

Other

No response

andreialecu avatar Aug 26 '22 12:08 andreialecu

If I revert to 10.0.18 the error disappears, it appears in 10.0.19.

andreialecu avatar Aug 26 '22 13:08 andreialecu

I have the same issue just for reference:

  @ResolveField(() => Organization)
  async organization(@Parent() { organizationId }: Invitation): Promise<Partial<Organization> | Error> {
    return this.organizationService.load(organizationId)
  }
@ObjectType()
@Directive('@key(fields: "_id")')
export class Organization {
  @Field(() => ObjectId)
  _id: ObjectId

  @Field(() => Date)
  createdAt: Date

  @Field(() => Date)
  updatedAt: Date
}

Error:

CannotDetermineInputTypeError: Cannot determine a GraphQL input type ("Organization") for the "organization". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create (/Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type.factory.js:19:23)
    at /Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:48:52
    at Array.forEach (<anonymous>)
    at /Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:46:33

This still works properly for cases where I implement ObjectType and InputType simultaneous:

@ObjectType()
@InputType('MinimalUserInput')
export class MinimalUser extends PickType(User, [
  '_id',
  'name',
  'familyName',
  'givenName',
  'middleName',
  'nickname',
  'picture',
] as const) {
  @Field({ nullable: true })
  picture?: string
}

But I cannot do this with most of the cases because even apart from business logic constrains it then hit what it seams another bug where you cannot implement InputType and directives like "Key" or "shareable" with "InputType".

JonnyBGod avatar Aug 26 '22 13:08 JonnyBGod

This looks like a regression caused by this PR cc @roypeled https://github.com/nestjs/graphql/pull/2212

Could any of you @andreialecu @JonnyBGod provide a minimum reproduction repository to help us fix this issue asap?

kamilmysliwiec avatar Aug 29 '22 09:08 kamilmysliwiec

I am a bit busy but will try to get it for you later today.

There is another issue that maybe you can chack at the same time. Or if you prefer let me know and I will create a separate issue.

The problem shows when using ObjectType and InutType simultaneously and also applying directives such as Key and Shareable. It throws errors syaing that you cannot use these directives with InputType. ideally it should ignore or dtripp these directives for the InputType metadata.

JonnyBGod avatar Aug 29 '22 14:08 JonnyBGod

FWIW I worked around this by declaring the field on the entity.

class Entity {
  @Field(...)
  foo?: never;
}

@Resolver(Entity)
class Resolver {
  @ResolveField()
  foo() { ... }
}

CarsonF avatar Aug 30 '22 15:08 CarsonF

Sorry did not manage to replicate with a simple repo yet. It looks odd, trying to replicate two of my entities simplified and it is working well on a simple repo. Also tried with abstract class extentions and still works.

Also removed most of my package versioning conflicts on my project (thought it could be a graphql version conflivting). still did not solve this. Tried https://github.com/nestjs/graphql/issues/2360#issuecomment-1231834995 with no luck as well.

Will keep investigating...

JonnyBGod avatar Aug 30 '22 21:08 JonnyBGod

@kamilmysliwiec repro at: https://github.com/andreialecu/nest-repro-2360

yarn start

...
Error: Cannot determine a GraphQL input type ("OtherEntity") for the "test123". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create (/Users/andreialecu/Work/contrib/nestjs/nest-repro-2360/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type.factory.js:19:23)
    at /Users/andreialecu/Work/contrib/nestjs/nest-repro-2360/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:48:52
    at Array.forEach (<anonymous>)

andreialecu avatar Aug 31 '22 08:08 andreialecu

As a side note: It would be great if the error message above pointed to something more specific for other cases where it is more legitimate.

In our actual project, we have similarly named fields across multiple resolvers. It was impossible to pinpoint which one it was throwing on without directly troubleshooting the NestJS source code.

andreialecu avatar Aug 31 '22 08:08 andreialecu

I've run into the same issue, but I don't see much activity here - @andreialecu have you by any chance discovered a workaround?

jhpierce avatar Mar 19 '23 18:03 jhpierce

Hey everyone, sorry for the late reply, I realize it was my refactor of metadata storage that caused this issue. I didn't notice this issue before, and I just got an email with a comment update.

Here is the fix: https://github.com/nestjs/graphql/pull/2724

@kamilmysliwiec I would appreciate a merge, and if you can find the time to create a test for this case it would be amazing, I tried but for some reason I couldn't get the test to work with field resolver.

I did test the repro: https://github.com/andreialecu/nest-repro-2360 and the fix worked for that.

roypeled avatar Mar 19 '23 22:03 roypeled