angular/components · error · SchematicsException
Could not read Angular module file: ${modulePath}
Error message
Could not read Angular module file: ${modulePath} What it means
hasNgModuleImport reads the module file with tree.read(modulePath) before parsing; a null return means the file does not exist in the schematic Tree, so it throws this SchematicsException. This is a pre-parse existence check so the failure names the unreadable file.
Source
Thrown at src/cdk/schematics/utils/ast/ng-module-imports.ts:19
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {SchematicsException, Tree} from '@angular-devkit/schematics';
import * as ts from 'typescript';
/**
* 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' ||View on GitHub (pinned to 0411926e7d)
Solutions
- Check the path exists before calling: tree.exists(modulePath) — and use the correct path when it returns false.
- Run the schematic from the workspace root so relative module paths resolve correctly.
- If the file was created earlier in the same schematic run, confirm the rule committed the change to the Tree before reading it.
- Update the utility's caller to use the project's actual root from workspace.getProject(target).sourceRoot.
Example fix
// before
hasNgModuleImport(tree, 'src/app/app.module.ts', 'BrowserAnimationsModule');
// after
const modulePath = 'src/app/app.module.ts';
if (!tree.exists(modulePath)) {
throw new Error(`Module file missing: ${modulePath}`);
}
hasNgModuleImport(tree, modulePath, 'BrowserAnimationsModule'); Defensive patterns
Strategy: validation
Validate before calling
import { Tree } from '@angular-devkit/schematics';
function canReadModule(tree: Tree, modulePath: string): boolean {
return typeof modulePath === 'string' && tree.exists(modulePath);
}
if (!canReadModule(tree, modulePath)) {
throw new Error(`Fix modulePath before calling hasNgModuleImport: ${modulePath}`);
} Type guard
function isReadablePath(tree: Tree, path: unknown): path is string {
return typeof path === 'string' && path.length > 0 && tree.exists(path);
} Try / catch
try {
const has = hasNgModuleImport(tree, modulePath, className);
} catch (e) {
if (e instanceof SchematicsException && e.message.startsWith('Could not read Angular module file:')) {
console.warn(`Module file unreadable: ${modulePath}`);
return false;
}
throw e;
} Prevention
- Check tree.exists(modulePath) before reading.
- Resolve module paths from the target project's sourceRoot, not templates.
- Run from workspace root in multi-project repos.
- If you created the file in the same run, ensure the prior Rule flushed to the Tree.
When it happens
Trigger: hasNgModuleImport(tree, modulePath, className) called with a path outside the Tree's root, a misspelled module file name, or when the schematic's tree lacks the file because a prior rule wrote it to a different path (the in-memory Tree diverged from disk).
Common situations: Using this utility in setup/side-menu schematics of component libraries where the app module path is guessed from templates (e.g. src/app/app.module.ts) but the workspace layout differs (Nx apps/, libs/), or invoking a schematic from a subdirectory so relative paths resolve against the wrong root.
Related errors
- Could not find file for path: ${path}
- Module not found: ${modulePath}
- File ${modulePath} does not exist.
- Could not read file for path: ${htmlFilePath}
- Cannot read "${filePath}" because it does not exist.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/21570e17c1810317.
Report an issue: GitHub.