{"record":{"id":"21570e17c1810317","repo":"angular/components","slug":"could-not-read-angular-module-file-modulepath","errorCode":null,"errorMessage":"Could not read Angular module file: ${modulePath}","messagePattern":"Could not read Angular module file: (.+?)","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"src/cdk/schematics/utils/ast/ng-module-imports.ts","lineNumber":19,"sourceCode":"/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {SchematicsException, Tree} from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\n\n/**\n * Whether the Angular module in the given path imports the specified module class name.\n */\nexport function hasNgModuleImport(tree: Tree, modulePath: string, className: string): boolean {\n  const moduleFileContent = tree.read(modulePath);\n\n  if (!moduleFileContent) {\n    throw new SchematicsException(`Could not read Angular module file: ${modulePath}`);\n  }\n\n  const parsedFile = ts.createSourceFile(\n    modulePath,\n    moduleFileContent.toString(),\n    ts.ScriptTarget.Latest,\n    true,\n  );\n  const ngModuleMetadata = findNgModuleMetadata(parsedFile);\n\n  if (!ngModuleMetadata) {\n    throw new SchematicsException(`Could not find NgModule declaration inside: \"${modulePath}\"`);\n  }\n\n  for (let property of ngModuleMetadata!.properties) {\n    if (\n      !ts.isPropertyAssignment(property) ||\n      property.name.getText() !== 'imports' ||","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/schematics/utils/ast/ng-module-imports.ts#L1-L37","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nhasNgModuleImport(tree, 'src/app/app.module.ts', 'BrowserAnimationsModule');\n// after\nconst modulePath = 'src/app/app.module.ts';\nif (!tree.exists(modulePath)) {\n  throw new Error(`Module file missing: ${modulePath}`);\n}\nhasNgModuleImport(tree, modulePath, 'BrowserAnimationsModule');","handlingStrategy":"validation","validationCode":"import { Tree } from '@angular-devkit/schematics';\nfunction canReadModule(tree: Tree, modulePath: string): boolean {\n  return typeof modulePath === 'string' && tree.exists(modulePath);\n}\nif (!canReadModule(tree, modulePath)) {\n  throw new Error(`Fix modulePath before calling hasNgModuleImport: ${modulePath}`);\n}","typeGuard":"function isReadablePath(tree: Tree, path: unknown): path is string {\n  return typeof path === 'string' && path.length > 0 && tree.exists(path);\n}","tryCatchPattern":"try {\n  const has = hasNgModuleImport(tree, modulePath, className);\n} catch (e) {\n  if (e instanceof SchematicsException && e.message.startsWith('Could not read Angular module file:')) {\n    console.warn(`Module file unreadable: ${modulePath}`);\n    return false;\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["angular","schematics","file-not-found","tree-read"],"backgroundTag":"module-file-not-found","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}