{"id":"df638087e29d3e4b","repo":"nestjs/nest","slug":"the-invalid-grpc-decorator-method-metadata-rpc","errorCode":null,"errorMessage":"The invalid gRPC decorator (method \"${metadata.rpc}\" in service \"${metadata.service}\")","messagePattern":"The invalid gRPC decorator \\(method \"(.+?)\" in service \"(.+?)\"\\)","errorType":"exception","errorClass":"InvalidGrpcDecoratorException","httpStatus":null,"severity":"error","filePath":"packages/microservices/decorators/message-pattern.decorator.ts","lineNumber":94,"sourceCode":"        descriptor.value,\n      );\n      Reflect.defineMetadata(\n        PATTERN_HANDLER_METADATA,\n        PatternHandler.MESSAGE,\n        descriptor.value,\n      );\n      Reflect.defineMetadata(TRANSPORT_METADATA, transport, descriptor.value);\n      Reflect.defineMetadata(\n        PATTERN_EXTRAS_METADATA,\n        {\n          ...Reflect.getMetadata(PATTERN_EXTRAS_METADATA, descriptor.value),\n          ...extras,\n        },\n        descriptor.value,\n      );\n      return descriptor;\n    } catch (err) {\n      throw new InvalidGrpcDecoratorException(metadata as RpcDecoratorMetadata);\n    }\n  };\n};\n\n/**\n * Registers gRPC method handler for specified service.\n */\nexport function GrpcMethod(service?: string): MethodDecorator;\nexport function GrpcMethod(service: string, method?: string): MethodDecorator;\nexport function GrpcMethod(\n  service: string | undefined,\n  method?: string,\n): MethodDecorator {\n  return (\n    target: object,\n    key: string | symbol,\n    descriptor: PropertyDescriptor,\n  ) => {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/nestjs/nest/blob/6ec0e2783d15290732447f304d8549b591b9749e/packages/microservices/decorators/message-pattern.decorator.ts#L76-L112","documentation":"Thrown as InvalidGrpcDecoratorException from inside the MessagePattern decorator factory when the try block that calls Reflect.defineMetadata(...) throws. The factory wraps defineMetadata calls for PATTERN_METADATA, PATTERN_HANDLER_METADATA, TRANSPORT_METADATA, and PATTERN_EXTRAS_METADATA; any failure there (most commonly a malformed decorator argument or an un-decoratable target) is rethrown with the offending service/method metadata for diagnosis. The message names the rpc method and service derived by createGrpcMethodMetadata.","triggerScenarios":"Applying @MessagePattern / @GrpcMethod / @GrpcStreamMethod / @GrpcStreamCall to something that is not a valid method descriptor (e.g. on a getter, or with a target whose descriptor.value is non-extensible/frozen). Passing a metadata object that causes ([]).concat(metadata) to throw. Decorator applied where the descriptor or target is null/invalid (manual decorator invocation).","commonSituations":"Custom build/Babel/swc transform that changes property descriptors so Reflect.defineMetadata throws. Applying the decorator to a static or arrow-function property whose descriptor lacks the normal shape. Manual Reflect metadata polyfill missing in the runtime, so defineMetadata fails. Applying @GrpcMethod to a class field instead of a method.","solutions":["Ensure @GrpcMethod/@GrpcStreamMethod/@GrpcStreamCall decorate a normal method (not a getter, field, or arrow-function class property).","Confirm emitDecoratorMetadata and experimentalDecorators are enabled in tsconfig and the Reflect metadata polyfill is imported (import 'reflect-metadata').","Avoid manually invoking the decorator with a fabricated descriptor; use the normal @ syntax.","If using a custom transformer (swc/esbuild), verify it preserves method descriptors compatible with legacy decorators."],"exampleFix":"// before\nclass UsersController {\n  @GrpcMethod() // applied to an arrow-function field\n  getUser = (req) => { ... };\n}\n\n// after\nclass UsersController {\n  @GrpcMethod()\n  getUser(req) { ... }\n}","handlingStrategy":"validation","validationCode":"// Validate decorator target before applying (for programmatic decorator use)\nfunction isMethodDescriptor(target: any, key: string | symbol, desc: PropertyDescriptor): boolean {\n  return !!desc && typeof desc.value === 'function';\n}\n// Prefer using the @ decorator syntax on plain methods to avoid this entirely.","typeGuard":"const isGrpcDecoratorError = (e: unknown): boolean =>\n  /invalid gRPC decorator/.test((e as Error)?.message ?? '');","tryCatchPattern":"// This throws at decoration time (module load), so there is no runtime catch site.\n// Fix by ensuring decorators are applied to plain methods and reflect-metadata is imported.","preventionTips":["Apply @GrpcMethod / @GrpcStreamMethod / @GrpcStreamCall only to normal methods.","Enable experimentalDecorators and emitDecoratorMetadata; import 'reflect-metadata' at app entry.","If using swc/esbuild, confirm legacy-decorator compatibility."],"tags":["grpc","decorators","metadata","reflect-metadata","typescript"],"analyzedSha":"6ec0e2783d15290732447f304d8549b591b9749e","analyzedAt":"2026-08-03T17:42:23.673Z","schemaVersion":2}