nestjs/nest · warning

The "instanceDecorator" function threw an error while decora

Error message

The "instanceDecorator" function threw an error while decorating an instance (${(err as Error)?.message ?? err}). The undecorated instance will be used instead.

What it means

This warning is emitted by NestJS's instrumentation layer when the user-configured `instrument.instanceDecorator` hook (set via `Instrument` in `NestFactory.create` options) throws while wrapping a resolved provider instance. The framework wraps the decorator with `makeSafeInstanceDecorator` so that a broken decorator never crashes bootstrap: it logs this warning and falls back to using the original, undecorated instance. It is a resilience message, not a fatal error — the app keeps running, but instrumentation (tracing/metrics patching) is silently missing for that instance.

Source

Thrown at packages/core/helpers/safe-instance-decorator.ts:21

type InstanceDecorator = (target: unknown) => unknown;

const logger = new Logger('InstrumentLogger');

/**
 * Wraps an `instrument.instanceDecorator` so that a decorator throwing on a
 * given instance (e.g. when inspecting a Proxy whose traps throw outside of
 * their intended context, such as `nestjs-cls` proxy providers) does not
 * crash the application bootstrap. The original, undecorated instance is
 * used instead and a warning is logged.
 */
export function makeSafeInstanceDecorator(
  decorator: InstanceDecorator,
): InstanceDecorator {
  return (target: unknown) => {
    try {
      return decorator(target);
    } catch (err) {
      logger.warn(
        `The "instanceDecorator" function threw an error while decorating an instance (${
          (err as Error)?.message ?? err
        }). The undecorated instance will be used instead.`,
      );
      return target;
    }
  };
}

View on GitHub (pinned to 3f8a0ce183)

Solutions

  1. Inspect the underlying message in the parentheses (the original thrown error) — it names the real cause; fix that (e.g. guard against Proxy objects in your decorator).
  2. If using nestjs-cls proxy providers, wrap your instanceDecorator body in a check that skips Proxy/exotic instances (e.g. try accessing a marker property inside its own try/catch, or duck-type on the design token) instead of patching them.
  3. Make your instanceDecorator defensive: never spread/clone/`Object.keys` the target; only wrap it in a new Proxy or attach methods, and catch its own errors internally.
  4. If you never configured instrumentation, this warning is harmless — the undecorated instance is used and behavior is unchanged; you can silence it via logger levels.
  5. Check for version mismatch between @nestjs/core and your instrumentation/telemetry packages and align them.

Example fix

// before (in main.ts)
const app = await NestFactory.create(AppModule, {
  instrument: {
    instanceDecorator: (instance) => {
      const copy = { ...instance }; // throws on proxies w/ throwing traps
      patchMethods(copy);
      return copy;
    },
  },
});

// after
const app = await NestFactory.create(AppModule, {
  instrument: {
    instanceDecorator: (instance) => {
      if (instance == null || (typeof instance !== 'object' && typeof instance !== 'function')) {
        return instance;
      }
      try {
        // only wrap, never clone/inspect
        return new Proxy(instance, tracingHandler);
      } catch {
        return instance; // degrade gracefully yourself
      }
    },
  },
});
Defensive patterns

Strategy: try-catch

Validate before calling

// Before assigning the hook, smoke-test it on benign and hostile targets:
const decorator = (i: unknown) => { /* your impl */ };
for (const probe of [{}, () => {}, new Proxy({}, { get() { throw new Error('trap'); } })]) {
  try { decorator(probe); } catch (e) {
    console.warn('instanceDecorator unsafe on', probe, e);
  }
}
const app = await NestFactory.create(AppModule, {
  instrument: { instanceDecorator: makeDefensive(decorator) },
});

Type guard

function isPlainDecoratable(target: unknown): boolean {
  if (target === null || (typeof target !== 'object' && typeof target !== 'function')) return false;
  try {
    // probes that typically throw on exotic proxies
    Object.getPrototypeOf(target);
    return true;
  } catch {
    return false;
  }
}

Try / catch

// Wrap your own decorator so IT never throws; Nest only warns-and-falls-back
const safeDecorator = (instance: unknown) => {
  try {
    return myInstrumentDecorator(instance);
  } catch (err) {
    myLogger.warn(`skipping instrumentation for instance: ${err}`);
    return instance; // must return the original target
  }
};

Prevention

When it happens

Trigger: Passing a custom `instanceDecorator` in the `instrument` options of `NestFactory.create()` / microservice / standalone app creation, and that decorator throwing on a specific instance. Known concrete trigger: decorating Proxy-based providers (e.g. `nestjs-cls` proxy providers) whose traps throw when the decorator inspects or clones the proxy; also any decorator that accesses properties (e.g. `Object.keys`, spread, `instance.constructor`) on exotic objects that throw on property access.

Common situations: Upgrading NestJS to a version that added the instanceDecorator instrumentation hook while using OpenTelemetry or tracing wrappers that assume plain objects; using `nestjs-cls` with `proxyProviders` (the documented culprit in the code comment); decorators that call `JSON.stringify` or iterate over instances with getters that throw; partially-initialized instances decorated during eager instantiation.

Related errors


AI-assisted analysis of nestjs/nest@3f8a0ce183 (2026-08-27). Data as JSON: /api/errors/c5065bea97d05e80. Report an issue: GitHub.