nestjs/nest · critical · UndefinedModuleException

Nest cannot create the ${parentModule.name} instance. The mo

Error message

Nest cannot create the ${parentModule.name} instance.
The module at index [${index}] of the ${parentModule.name} "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [${index}] is of type "undefined". Check your import statements and the type of the module.

Scope [${scope}]

What it means

While the module scanner walks each module's `imports` array, it checks every entry for `undefined` first: with circular ES module imports, a class binding that is referenced before its module finished evaluating resolves to `undefined` exactly. UndefinedModuleException ('The module at index [i] of the imports array is undefined... Potential causes: circular dependency...') names the offending index and the import scope so you can find the cycle.

Source

Thrown at packages/core/scanner.ts:152

      moduleDefinition as Type<any> | DynamicModule,
    )
      ? this.reflectMetadata(
          MODULE_METADATA.IMPORTS,
          moduleDefinition as Type<any>,
        )
      : [
          ...this.reflectMetadata(
            MODULE_METADATA.IMPORTS,
            (moduleDefinition as DynamicModule).module,
          ),
          ...((moduleDefinition as DynamicModule).imports || []),
        ];

    let registeredModuleRefs: Module[] = [];
    for (const [index, innerModule] of modules.entries()) {
      // In case of a circular dependency (ES module system), JavaScript will resolve the type to `undefined`.
      if (innerModule === undefined) {
        throw new UndefinedModuleException(moduleDefinition, index, scope);
      }
      if (!innerModule) {
        throw new InvalidModuleException(
          moduleDefinition,
          index,
          scope,
          innerModule,
        );
      }
      if (ctxRegistry.includes(innerModule)) {
        continue;
      }
      const moduleRefs = await this.scanForModules({
        moduleDefinition: innerModule,
        scope: ([] as Array<Type>).concat(scope, moduleDefinition as Type),
        ctxRegistry,
        overrides,
        lazy,

View on GitHub (pinned to dd75d7bd8c)

Solutions

  1. Break the module cycle: for circular module dependencies use `forwardRef(() => OtherModule)` inside `imports`.
  2. More commonly, break the underlying provider cycle (move the shared provider to a third module both import) so the modules no longer need each other.
  3. Fix conditional registration so it never yields undefined: `imports: [FeatureModule].filter(Boolean)` or spread a conditional array.
  4. Avoid importing modules via barrel files; import the module file directly.

Example fix

// before (a.module.ts <-> b.module.ts import each other)
@Module({ imports: [BModule] }) export class AModule {}
@Module({ imports: [AModule] }) export class BModule {} // BModule is undefined at scan time

// after
import { forwardRef } from '@nestjs/common';
@Module({ imports: [forwardRef(() => BModule)] }) export class AModule {}
@Module({ imports: [forwardRef(() => AModule)] }) export class BModule {}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-bootstrap scan: no undefined entries anywhere in module imports arrays
import 'reflect-metadata';

function assertImportsDefined(module: Function, seen = new Set<Function>()) {
  if (seen.has(module)) return;
  seen.add(module);
  const imports: any[] = Reflect.getMetadata('imports', module) ?? [];
  imports.forEach((m, i) => {
    if (m === undefined) {
      throw new Error(`${module.name}: imports[${i}] is undefined — circular module import or bad conditional`);
    }
    if (typeof m === 'function') assertImportsDefined(m, seen);
  });
}

Type guard

const isDefinedModule = (v: any): v is import('@nestjs/common').Type<any> =>
  typeof v === 'function' && v !== undefined;

Try / catch

try {
  await NestFactory.create(AppModule);
} catch (e: any) {
  if (/module at index \[\d+\].*is undefined/i.test(String(e?.message))) {
    console.error(e.message); // includes index + scope chain to locate the cycle
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Module A imports Module B while B (directly or through a chain/barrel) imports A — at scan time one binding is undefined; a conditional import evaluates to undefined (`imports: [cond ? FeatureModule : undefined]`); importing a module from a barrel file participating in a cycle; importing a module that re-exports through a cycle.

Common situations: Two feature modules referencing each other's services so developers import the modules mutually; `index.ts` barrels creating hidden cycles; environment-driven feature toggles injected into imports arrays; NestJS 11+ strictness exposing cycles that previously slipped through.

Related errors


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