nestjs/nest · error · Error

Calling the "${methodName}" in the preview mode is not suppo

Error message

Calling the "${methodName}" in the preview mode is not supported.

What it means

With `NestFactory.create(AppModule, { preview: true })` NestJS builds the whole DI graph and route table but never starts a server — it exists for compile-time analysis (e.g., CI checks of module wiring and route registration). Runtime-only entry points are guarded by assertNotInPreviewMode: calling `listen()`, `startAllMicroservices()`, `close()` (or other guarded lifecycle methods) in preview mode throws immediately with 'Calling the "X" in the preview mode is not supported.'.

Source

Thrown at packages/core/nest-application-context.ts:483

  /**
   * Calls the `beforeApplicationShutdown` function on the registered
   * modules and children.
   */
  protected async callBeforeShutdownHook(signal?: string): Promise<void> {
    const modulesSortedByDistance = [
      ...this.getModulesToTriggerHooksOn(),
    ].reverse();

    for (const module of modulesSortedByDistance) {
      await callBeforeAppShutdownHook(module, signal);
    }
  }

  protected assertNotInPreviewMode(methodName: string) {
    if (this.appOptions.preview) {
      const error = `Calling the "${methodName}" in the preview mode is not supported.`;
      this.logger.error(error);
      throw new Error(error);
    }
  }

  private getModulesToTriggerHooksOn(): Module[] {
    if (this._moduleRefsForHooksByDistance) {
      return this._moduleRefsForHooksByDistance;
    }
    const modulesContainer = this.container.getModules();
    const compareFn = (a: Module, b: Module) => b.distance - a.distance;
    const modulesSortedByDistance = Array.from(modulesContainer.values()).sort(
      compareFn,
    );

    this._moduleRefsForHooksByDistance = this.appOptions?.preview
      ? modulesSortedByDistance.filter(moduleRef => moduleRef.initOnPreview)
      : modulesSortedByDistance;
    return this._moduleRefsForHooksByDistance;
  }

View on GitHub (pinned to dd75d7bd8c)

Solutions

  1. Gate the runtime calls: only call `listen()`/`startAllMicroservices()` when preview is disabled.
  2. Derive `preview` from one explicit env variable and reuse the same variable for the gate.
  3. Split entrypoints: main.ts for serving, a separate preview.ts for compile-time checks.
  4. Verify the flag in the deployed environment (NEST_PREVIEW / APP_PREVIEW) is not stuck at true.

Example fix

// before
const app = await NestFactory.create(AppModule, { preview: isPreview });
await app.listen(3000); // throws when isPreview

// after
const app = await NestFactory.create(AppModule, { preview: isPreview });
if (!isPreview) {
  await app.listen(3000);
}
Defensive patterns

Strategy: validation

Validate before calling

// Single source of truth for the mode; gate every runtime call on it
const isPreview = process.env.NEST_PREVIEW === 'true';
const app = await NestFactory.create(AppModule, { preview: isPreview });

if (!isPreview) {
  await app.listen(process.env.PORT ?? 3000);
  await app.startAllMicroservices(); // also guarded
}

Prevention

When it happens

Trigger: A single bootstrap file used both for `nest build --preview`-style checks and real serving: the `preview: true` option is left enabled (or toggled by env var) while the code still unconditionally calls `app.listen(port)` or `app.startAllMicroservices()`; CI pipelines flipping a PREVIEW env var without gating listen().

Common situations: Migrating CI to validate modules without binding ports; monorepos sharing one main.ts across deploy targets; env-driven config where NEST_PREVIEW stays 'true' in a deployed image by mistake.

Related errors


AI-assisted analysis of nestjs/nest@dd75d7bd8c (2026-08-21). Data as JSON: /api/errors/fa6c59cd1922a18e. Report an issue: GitHub.