angular/angular-cli · error

Unable to locate component resource: ${fileName}

Error message

Unable to locate component resource: ${fileName}

What it means

When the Angular compiler plugin host is set to load templates directly (options.directTemplateLoading) and a component references an .html or .svg resource, augmentHostWithResources overrides the resource loader to read the file from disk via this.readFile. If the read returns undefined, the resource cannot be found on disk, so it throws 'Unable to locate component resource: <fileName>' instead of letting the compiler proceed with a missing template.

Source

Thrown at packages/ngtools/webpack/src/ivy/host.ts:36

  host: ts.CompilerHost,
  resourceLoader: WebpackResourceLoader,
  options: {
    directTemplateLoading?: boolean;
    inlineStyleFileExtension?: string;
  } = {},
): void {
  const resourceHost = host as CompilerHost;

  resourceHost.readResource = function (fileName: string) {
    const filePath = normalizePath(fileName);

    if (
      options.directTemplateLoading &&
      (filePath.endsWith('.html') || filePath.endsWith('.svg'))
    ) {
      const content = this.readFile(filePath);
      if (content === undefined) {
        throw new Error('Unable to locate component resource: ' + fileName);
      }

      resourceLoader.setAffectedResources(filePath, [filePath]);

      return Promise.resolve(content);
    } else {
      return resourceLoader.get(filePath);
    }
  };

  resourceHost.resourceNameToFileName = function (resourceName: string, containingFile: string) {
    return path.join(path.dirname(containingFile), resourceName);
  };

  resourceHost.getModifiedResourceFiles = function () {
    return resourceLoader.getModifiedResourceFiles();
  };

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Fix the templateUrl/styleUrls path in the component so it points to the actual file relative to the component's location.
  2. Check filename casing exactly matches on disk (case-sensitive CI/Linux builds).
  3. If the file should exist, restore it or un-exclude it from the webpack/tsconfig build inputs.
  4. If you load templates through custom loaders/preprocessing, disable directTemplateLoading so resources go through the normal webpack pipeline instead of the host's direct file read.

Example fix

// before
@Component({
  templateUrl: './my-componnt.html', // typo: file does not exist
})

// after
@Component({
  templateUrl: './my-component.html',
})
Defensive patterns

Strategy: try-catch

Validate before calling

const path = require('path');
const fs = require('fs');
// for each @Component resource
const file = path.resolve(componentDir, templateUrl);
if (!fs.existsSync(file)) {
  console.error(`templateUrl target missing: ${file}`);
}
// also verify exact casing (CI/Linux)
const actual = fs.readdirSync(path.dirname(file)).find(f => f === path.basename(file));
if (!actual) console.error('casing mismatch or missing file');

Try / catch

try {
  const result = await build();
} catch (err) {
  if (/Unable to locate component resource:/.test(err.message)) {
    const missing = err.message.split('Unable to locate component resource: ')[1];
    console.error(`Fix templateUrl for missing file: ${missing}`);
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: A @Component decorator declares templateUrl or an SVG styleUrls entry pointing to a file that does not exist at the resolved path (wrong relative path, file deleted/renamed, case-mismatched filename on Linux, or the resource excluded from the build context). Raised during setupCompilation via the augmented host's resource resolution in an @ngtools/webpack build.

Common situations: Renaming or moving a component without updating templateUrl; case-sensitive file systems (Docker/CI Linux) where template.HTML worked on macOS/Windows; assets deleted by a clean script; paths built with string concatenation that resolve outside the project.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/7da6a30275b816df. Report an issue: GitHub.