nestjs/nest · error · InvalidGrpcDecoratorException

The invalid gRPC decorator (method "${metadata.rpc}" in serv

Error message

The invalid gRPC decorator (method "${metadata.rpc}" in service "${metadata.service}")

What it means

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.

Source

Thrown at packages/microservices/decorators/message-pattern.decorator.ts:94

        descriptor.value,
      );
      Reflect.defineMetadata(
        PATTERN_HANDLER_METADATA,
        PatternHandler.MESSAGE,
        descriptor.value,
      );
      Reflect.defineMetadata(TRANSPORT_METADATA, transport, descriptor.value);
      Reflect.defineMetadata(
        PATTERN_EXTRAS_METADATA,
        {
          ...Reflect.getMetadata(PATTERN_EXTRAS_METADATA, descriptor.value),
          ...extras,
        },
        descriptor.value,
      );
      return descriptor;
    } catch (err) {
      throw new InvalidGrpcDecoratorException(metadata as RpcDecoratorMetadata);
    }
  };
};

/**
 * Registers gRPC method handler for specified service.
 */
export function GrpcMethod(service?: string): MethodDecorator;
export function GrpcMethod(service: string, method?: string): MethodDecorator;
export function GrpcMethod(
  service: string | undefined,
  method?: string,
): MethodDecorator {
  return (
    target: object,
    key: string | symbol,
    descriptor: PropertyDescriptor,
  ) => {

View on GitHub (pinned to 6ec0e2783d)

Solutions

  1. Ensure @GrpcMethod/@GrpcStreamMethod/@GrpcStreamCall decorate a normal method (not a getter, field, or arrow-function class property).
  2. Confirm emitDecoratorMetadata and experimentalDecorators are enabled in tsconfig and the Reflect metadata polyfill is imported (import 'reflect-metadata').
  3. Avoid manually invoking the decorator with a fabricated descriptor; use the normal @ syntax.
  4. If using a custom transformer (swc/esbuild), verify it preserves method descriptors compatible with legacy decorators.

Example fix

// before
class UsersController {
  @GrpcMethod() // applied to an arrow-function field
  getUser = (req) => { ... };
}

// after
class UsersController {
  @GrpcMethod()
  getUser(req) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate decorator target before applying (for programmatic decorator use)
function isMethodDescriptor(target: any, key: string | symbol, desc: PropertyDescriptor): boolean {
  return !!desc && typeof desc.value === 'function';
}
// Prefer using the @ decorator syntax on plain methods to avoid this entirely.

Type guard

const isGrpcDecoratorError = (e: unknown): boolean =>
  /invalid gRPC decorator/.test((e as Error)?.message ?? '');

Try / catch

// This throws at decoration time (module load), so there is no runtime catch site.
// Fix by ensuring decorators are applied to plain methods and reflect-metadata is imported.

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of nestjs/nest@6ec0e2783d (2026-08-03). Data as JSON: /data/errors/df638087e29d3e4b.json. Report an issue: GitHub.