nestjs/nest · critical · InvalidModuleException
Nest cannot create the ${parentModule.name} instance. Receiv
Error message
Nest cannot create the ${parentModule.name} instance.
Received an unexpected value at index [${index}] of the ${parentModule.name} "imports" array.
The received value `${formattedValue}` is of type "${receivedType}".
Scope [${scope}] What it means
The scanner distinguishes `undefined` (circular-import signature) from other falsy values: any null, empty string, 0, false or NaN in a module's `imports` array raises InvalidModuleException ('Received an unexpected value at index [i] of the imports array... The received value X is of type Y'). It means an expression in the array evaluated to a non-module falsy value — a data/config artifact rather than a module class.
Source
Thrown at packages/core/scanner.ts:155
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,
});
registeredModuleRefs = registeredModuleRefs.concat(moduleRefs);
}View on GitHub (pinned to dd75d7bd8c)
Solutions
- Find the offending index in the error message and inspect the exact expression at that position in the `imports` array.
- Replace `flag && FeatureModule` with a conditional spread: `imports: [...(flag ? [FeatureModule] : [])]`.
- Sanitize assembled arrays: `imports: importedModules.filter(Boolean)` when the array is built from config.
- Give optional config a real default (`?? []`, `?? {}`) so the expression yields a module or nothing at all, never null/false.
Example fix
// before
@Module({
imports: [process.env.USE_FEATURE && FeatureModule, CoreModule], // false at index 0
})
// after
@Module({
imports: [
...(process.env.USE_FEATURE ? [FeatureModule] : []),
CoreModule,
],
}) Defensive patterns
Strategy: validation
Validate before calling
// Reject any non-module (falsy or otherwise) entry before Nest sees it
const isNestModuleLike = (v: any): boolean =>
typeof v === 'function' && !!v.prototype;
function sanitizeImports(imports: unknown[]): any[] {
const invalid = imports.filter(v => !isNestModuleLike(v));
if (invalid.length > 0) {
throw new Error(`Non-module entries in imports: ${invalid.map(String).join(', ')}`);
}
return imports.filter(Boolean) as any[];
}
// const dynamicImports = sanitizeImports([config?.module, FeatureModule]); Type guard
const isModuleClass = (v: unknown): v is abstract new (...a: any[]) => any => typeof v === 'function' && typeof (v as any).prototype === 'object';
Prevention
- Write feature toggles as conditional spreads, never `flag && Module` inline in the array.
- Default optional config with `?? []` so builders never emit null/false entries.
- Validate assembled dynamic imports with the isModuleClass guard in a wiring test.
When it happens
Trigger: `imports: [config?.module]` where config is null; `imports: [...(features ?? [])]` with an array containing nulls; destructured dynamic module config that yields `''` or `0` when a provider returns early; unit-test module builders receiving unstubbed values; `process.env.FLAG && FeatureModule` evaluating to false and being kept in the array.
Common situations: Optional dynamic modules assembled from configuration objects; feature-flagged imports written as `flag && Module` (false leaks into the array); mocks in tests returning null for module factories; refactors where a getter used to build imports returns empty values on edge cases.
Related errors
- An invalid controller has been detected. "${className}" does
- Nest cannot create the ${parentModule.name} instance. The mo
- "${metatype.name}" is decorated with @Injectable() and canno
- "${metatype.name}" is decorated with @Controller() and canno
- Nest cannot export a provider/module that is not a part of t
AI-assisted analysis of nestjs/nest@dd75d7bd8c (2026-08-21).
Data as JSON: /api/errors/2734e367d0332ba3.
Report an issue: GitHub.