angular/components · error · SchematicsException
Could not read file for path: ${htmlFilePath}
Error message
Could not read file for path: ${htmlFilePath} What it means
appendHtmlElementToHead in src/cdk/schematics/utils/html-manipulation.ts reads the target HTML file (normally the app's index.html) from the schematic virtual host Tree before appending an element to its <head>. If host.read(htmlFilePath) returns null the file does not exist at that path in the virtual file system, and a SchematicsException is thrown. The library cannot modify a file it cannot read, so it fails fast.
Source
Thrown at src/cdk/schematics/utils/html-manipulation.ts:18
/**
* @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 {Element, getChildElementIndentation} from './parse5-element';
import {parse as parseHtml} from 'parse5';
/** Appends the given element HTML fragment to the `<head>` element of the specified HTML file. */
export function appendHtmlElementToHead(host: Tree, htmlFilePath: string, elementHtml: string) {
const htmlFileBuffer = host.read(htmlFilePath);
if (!htmlFileBuffer) {
throw new SchematicsException(`Could not read file for path: ${htmlFilePath}`);
}
const htmlContent = htmlFileBuffer.toString();
if (htmlContent.includes(elementHtml)) {
return;
}
const headTag = getHtmlHeadTagElement(htmlContent);
if (!headTag) {
throw Error(`Could not find '<head>' element in HTML file: ${htmlFileBuffer}`);
}
// We always have access to the source code location here because the `getHeadTagElement`
// function explicitly has the `sourceCodeLocationInfo` option enabled.
const endTagOffset = headTag.sourceCodeLocation!.endTag!.startOffset;
const indentationOffset = getChildElementIndentation(headTag);View on GitHub (pinned to 0411926e7d)
Solutions
- Verify the project's build architect options in angular.json contain a correct "index" path and that the file exists on disk.
- Restore or recreate index.html at the configured path (a standard Angular app has src/index.html).
- If you use a custom index name, register it under projects.<name>.architect.build.options.index so schematics can resolve it.
- Re-run `ng build` or `ng serve` once to confirm the workspace resolves the index file, then retry the schematic.
Example fix
// before (angular.json)
"options": { "main": "src/main.ts" }
// after (angular.json)
"options": { "main": "src/main.ts", "index": "src/index.html" } Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'fs';
const index = JSON.parse(fs.readFileSync('angular.json', 'utf8'))
.projects[name]?.architect?.build?.options?.index ?? 'src/index.html';
if (!existsSync(index)) throw new Error(`index.html missing at ${index}`); Type guard
function hasIndexOption(opts: Record<string, unknown> | undefined): opts is Record<string, unknown> & { index: string } {
return !!opts && typeof opts.index === 'string';
} Try / catch
try {
await runSchematic('add-fonts', { project: name });
} catch (e) {
if (String(e.message).startsWith('Could not read file for path')) {
console.error('index.html not found; verify the project build "index" option.');
} else throw e;
} Prevention
- Keep index.html at src/index.html and registered in angular.json build options.
- Do not delete or rename index.html without updating the "index" config key.
- Run schematics from the workspace root so relative paths resolve.
When it happens
Trigger: Running a schematic that injects into index.html (e.g. addFontsToIndex for Material typography/fonts) when the resolved index path does not exist in the Tree; a project whose architect build options lack an index entry the schematic can resolve; an unusual custom index file name/location not registered in angular.json.
Common situations: Custom index filename (e.g. src/index.dev.html) not declared in angular.json; index.html deleted or moved during refactoring; monorepo layouts where sourceRoot does not point at the app root; running the schematic on a partially generated project.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Could not find file for path: ${path}
- Module not found: ${modulePath}
- Could not read Angular module file: ${modulePath}
- File ${modulePath} does not exist.
- Cannot read "${filePath}" because it does not exist.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/7c72ea9b36ec5b64.
Report an issue: GitHub.