{"record":{"id":"7da6a30275b816df","repo":"angular/angular-cli","slug":"unable-to-locate-component-resource-filename","errorCode":null,"errorMessage":"Unable to locate component resource: ${fileName}","messagePattern":"Unable to locate component resource: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ngtools/webpack/src/ivy/host.ts","lineNumber":36,"sourceCode":"  host: ts.CompilerHost,\n  resourceLoader: WebpackResourceLoader,\n  options: {\n    directTemplateLoading?: boolean;\n    inlineStyleFileExtension?: string;\n  } = {},\n): void {\n  const resourceHost = host as CompilerHost;\n\n  resourceHost.readResource = function (fileName: string) {\n    const filePath = normalizePath(fileName);\n\n    if (\n      options.directTemplateLoading &&\n      (filePath.endsWith('.html') || filePath.endsWith('.svg'))\n    ) {\n      const content = this.readFile(filePath);\n      if (content === undefined) {\n        throw new Error('Unable to locate component resource: ' + fileName);\n      }\n\n      resourceLoader.setAffectedResources(filePath, [filePath]);\n\n      return Promise.resolve(content);\n    } else {\n      return resourceLoader.get(filePath);\n    }\n  };\n\n  resourceHost.resourceNameToFileName = function (resourceName: string, containingFile: string) {\n    return path.join(path.dirname(containingFile), resourceName);\n  };\n\n  resourceHost.getModifiedResourceFiles = function () {\n    return resourceLoader.getModifiedResourceFiles();\n  };\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/ngtools/webpack/src/ivy/host.ts#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the templateUrl/styleUrls path in the component so it points to the actual file relative to the component's location.","Check filename casing exactly matches on disk (case-sensitive CI/Linux builds).","If the file should exist, restore it or un-exclude it from the webpack/tsconfig build inputs.","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."],"exampleFix":"// before\n@Component({\n  templateUrl: './my-componnt.html', // typo: file does not exist\n})\n\n// after\n@Component({\n  templateUrl: './my-component.html',\n})","handlingStrategy":"try-catch","validationCode":"const path = require('path');\nconst fs = require('fs');\n// for each @Component resource\nconst file = path.resolve(componentDir, templateUrl);\nif (!fs.existsSync(file)) {\n  console.error(`templateUrl target missing: ${file}`);\n}\n// also verify exact casing (CI/Linux)\nconst actual = fs.readdirSync(path.dirname(file)).find(f => f === path.basename(file));\nif (!actual) console.error('casing mismatch or missing file');","typeGuard":null,"tryCatchPattern":"try {\n  const result = await build();\n} catch (err) {\n  if (/Unable to locate component resource:/.test(err.message)) {\n    const missing = err.message.split('Unable to locate component resource: ')[1];\n    console.error(`Fix templateUrl for missing file: ${missing}`);\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Keep templateUrl/styleUrls paths relative to the component file and let your IDE auto-correct them on rename.","Match filename casing exactly; prefer kebab-case files so macOS/Windows edits survive Linux CI.","Run a pre-build lint rule that verifies referenced template/style files exist.","If using custom template preprocessing pipelines, disable directTemplateLoading so webpack loaders resolve resources instead of direct file reads."],"tags":["webpack","angular","aot","template","file-not-found"],"backgroundTag":"component-resource-not-found","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}