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
- Break the module cycle: for circular module dependencies use `forwardRef(() => OtherModule)` inside `imports`.
- 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.
- Fix conditional registration so it never yields undefined: `imports: [FeatureModule].filter(Boolean)` or spread a conditional array.
- 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
- Enforce eslint import/no-cycle across the module layer; cycles are the dominant cause.
- Use forwardRef(() => OtherModule) immediately when two modules must reference each other.
- Build conditional imports with spreads (`...(flag ? [Module] : [])`), never inline `cond && Module`.
- Import modules from their files, not from index.ts barrels.
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
- Nest can't resolve dependencies of the ${type.toString()}
- An invalid controller has been detected. "${className}" does
- Nest cannot create the ${parentModule.name} instance. Receiv
- "${metatype.name}" is decorated with @Injectable() and canno
- "${metatype.name}" is decorated with @Controller() and canno
AI-assisted analysis of nestjs/nest@dd75d7bd8c (2026-08-21).
Data as JSON: /api/errors/a2c4d301bab216fb.
Report an issue: GitHub.