angular/components · error · SchematicsException
Could not find NgModule declaration inside: "${modulePath}"
Error message
Could not find NgModule declaration inside: "${modulePath}" What it means
The module file was read and parsed, but findNgModuleMetadata could not locate an @NgModule(...) decorator expression in it, so hasNgModuleImport throws this SchematicsException. The file exists but is not a NgModule declaration file.
Source
Thrown at src/cdk/schematics/utils/ast/ng-module-imports.ts:31
* Whether the Angular module in the given path imports the specified module class name.
*/
export function hasNgModuleImport(tree: Tree, modulePath: string, className: string): boolean {
const moduleFileContent = tree.read(modulePath);
if (!moduleFileContent) {
throw new SchematicsException(`Could not read Angular module file: ${modulePath}`);
}
const parsedFile = ts.createSourceFile(
modulePath,
moduleFileContent.toString(),
ts.ScriptTarget.Latest,
true,
);
const ngModuleMetadata = findNgModuleMetadata(parsedFile);
if (!ngModuleMetadata) {
throw new SchematicsException(`Could not find NgModule declaration inside: "${modulePath}"`);
}
for (let property of ngModuleMetadata!.properties) {
if (
!ts.isPropertyAssignment(property) ||
property.name.getText() !== 'imports' ||
!ts.isArrayLiteralExpression(property.initializer)
) {
continue;
}
if (property.initializer.elements.some(element => element.getText() === className)) {
return true;
}
}
return false;
}View on GitHub (pinned to 0411926e7d)
Solutions
- Pass the file that actually contains @NgModule({ imports: [...] }); search the project for '@NgModule' if unsure.
- If the app is standalone, replace the NgModule check: add the module's exports to the component's imports array and skip hasNgModuleImport.
- Ensure @NgModule is imported from '@angular/core' in the target file (aliased decorators won't be found).
- Use the project's root module path from angular.json/workspace config instead of a hardcoded guess.
Example fix
// before hasNgModuleImport(tree, 'src/app/index.ts', 'MatDialogModule'); // after hasNgModuleImport(tree, 'src/app/app.module.ts', 'MatDialogModule'); // file containing @NgModule
Defensive patterns
Strategy: type-guard
Validate before calling
import * as ts from 'typescript';
function containsNgModule(content: string): boolean {
return /@NgModule\s*\(/.test(content);
}
const content = tree.read(modulePath)?.toString('utf-8') ?? '';
if (!containsNgModule(content)) {
throw new Error(`${modulePath} has no @NgModule; pick the root module`);
} Type guard
function isNgModuleFile(tree: Tree, modulePath: string): boolean {
const content = tree.exists(modulePath) ? tree.read(modulePath)!.toString('utf-8') : '';
return /@NgModule\s*\(/.test(content);
} Try / catch
try {
hasNgModuleImport(tree, modulePath, className);
} catch (e) {
if (e instanceof SchematicsException && e.message.includes('Could not find NgModule declaration')) {
console.warn(`${modulePath} is not an NgModule (standalone app or wrong file)`);
return false;
}
throw e;
} Prevention
- Regex-check the file for @NgModule before parsing it as a module.
- Never pass index.ts barrels or routing-only files to module-inspection utilities.
- Detect standalone apps (bootstrapApplication in main.ts) and skip NgModule logic.
- Track decorator imports: @NgModule must be imported from @angular/core, unaliased.
When it happens
Trigger: hasNgModuleImport(tree, modulePath, className) pointed at a TS file that has no @NgModule decorator: a standalone component/directive file, a barrel index.ts, a module with a typo'd decorator import, or a file where @NgModule is aliased.
Common situations: Migrating to Angular 14+ standalone APIs where app.module.ts was deleted in favor of main.ts bootstrapApplication, but older schematic setup rules still reference it; accidentally passing a routing.module.ts that only declares routes; passing index.ts re-export files.
Related errors
- Module not found: ${modulePath}
- Cannot read "${filePath}" because it does not exist.
- No data could be found for target version: ${version}
- Could not find file for path: ${path}
- Could not read Angular module file: ${modulePath}
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/9f9320ca533f8835.
Report an issue: GitHub.