nestjs/nest · error · InvalidExceptionFilterException

Invalid exception filters (@UseFilters()).

Error message

Invalid exception filters (@UseFilters()).

What it means

Thrown as InvalidExceptionFilterException ('Invalid exception filters (@UseFilters()).') from RpcExceptionsHandler.setCustomFilters() when the filters argument is not an Array. The RPC exception handler expects the @UseFilters() metadata to resolve to an array of filter instances/classes; if a single non-array value (or undefined) is passed in, registration is rejected before any exception is handled.

Source

Thrown at packages/microservices/exceptions/rpc-exceptions-handler.ts:29

 * @publicApi
 */
export class RpcExceptionsHandler extends BaseRpcExceptionFilter {
  private filters: RpcExceptionFilterMetadata[] = [];

  public handle(
    exception: Error | RpcException,
    host: ArgumentsHost,
  ): Observable<any> {
    const filterResult$ = this.invokeCustomFilters(exception, host);
    if (filterResult$) {
      return filterResult$;
    }
    return super.catch(exception, host);
  }

  public setCustomFilters(filters: RpcExceptionFilterMetadata[]) {
    if (!Array.isArray(filters)) {
      throw new InvalidExceptionFilterException();
    }
    this.filters = filters;
  }

  public invokeCustomFilters<T = any>(
    exception: T,
    host: ArgumentsHost,
  ): Observable<any> | null {
    if (isEmpty(this.filters)) {
      return null;
    }

    const filter = selectExceptionFilterMetadata(this.filters, exception);
    return filter ? filter.func(exception, host) : null;
  }
}

View on GitHub (pinned to 6ec0e2783d)

Solutions

  1. Pass filter classes/instances as an array literal to @UseFilters(): @UseFilters(RpcExceptionFilter) or @UseFilters([FilterA, FilterB]).
  2. If calling setCustomFilters directly, pass an array: handler.setCustomFilters([myFilter]).
  3. Audit custom decorators wrapping @UseFilters to ensure they forward an array of filters.
  4. Update third-party exception-filter plugins to the NestJS version you are running.

Example fix

// before
@UseFilters() // empty or malformed
@MessagePattern('getUser')
get() {...}

// after
@UseFilters(new RpcExceptionFilter())
@MessagePattern('getUser')
get() {...}
Defensive patterns

Strategy: validation

Validate before calling

function normalizeFilters(filters: unknown): any[] {
  if (filters == null) return [];
  return Array.isArray(filters) ? filters : [filters];
}
// Pass the normalized array to @UseFilters / setCustomFilters.

Type guard

const isInvalidFiltersError = (e: unknown): boolean =>
  /Invalid exception filters/.test((e as Error)?.message ?? '');

Try / catch

// This throws during filter registration (startup), not per-request.
// Ensure @UseFilters receives filter classes/instances (or an array of them).

Prevention

When it happens

Trigger: Applying @UseFilters() with no arguments, or with a malformed argument, that resolves to a non-array when NestJS collects filter metadata. Programmatically calling handler.setCustomFilters(someFilter) with a single filter instead of [someFilter]. Custom decorator that mangles the UseFilters metadata into a non-array.

Common situations: @UseFilters() written with empty parentheses and an accidental non-array payload from a custom decorator. Misuse of the internal RpcExceptionsHandler via custom adapters. Framework version mismatch where UseFilters metadata shape changed and a third-party plugin still emits the old shape.

Related errors


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