{"record":{"id":"c589d5c40dff0c61","repo":"angular/components","slug":"could-not-find-head-element-in-html-file-ht","errorCode":null,"errorMessage":"Could not find '<head>' element in HTML file: ${htmlFileBuffer}","messagePattern":"Could not find '<head>' element in HTML file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/schematics/utils/html-manipulation.ts","lineNumber":30,"sourceCode":"\n/** Appends the given element HTML fragment to the `<head>` element of the specified HTML file. */\nexport function appendHtmlElementToHead(host: Tree, htmlFilePath: string, elementHtml: string) {\n  const htmlFileBuffer = host.read(htmlFilePath);\n\n  if (!htmlFileBuffer) {\n    throw new SchematicsException(`Could not read file for path: ${htmlFilePath}`);\n  }\n\n  const htmlContent = htmlFileBuffer.toString();\n\n  if (htmlContent.includes(elementHtml)) {\n    return;\n  }\n\n  const headTag = getHtmlHeadTagElement(htmlContent);\n\n  if (!headTag) {\n    throw Error(`Could not find '<head>' element in HTML file: ${htmlFileBuffer}`);\n  }\n\n  // We always have access to the source code location here because the `getHeadTagElement`\n  // function explicitly has the `sourceCodeLocationInfo` option enabled.\n  const endTagOffset = headTag.sourceCodeLocation!.endTag!.startOffset;\n  const indentationOffset = getChildElementIndentation(headTag);\n  const insertion = `${' '.repeat(indentationOffset)}${elementHtml}`;\n\n  const recordedChange = host.beginUpdate(htmlFilePath).insertRight(endTagOffset, `${insertion}\\n`);\n\n  host.commitUpdate(recordedChange);\n}\n\n/** Parses the given HTML file and returns the head element if available. */\nexport function getHtmlHeadTagElement(htmlContent: string): Element | null {\n  return getElementByTagName('head', htmlContent);\n}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/schematics/utils/html-manipulation.ts#L12-L48","documentation":"Thrown by the CDK schematics helper appendHtmlElementToHead when it parses an index.html file and cannot locate a <head> tag. Migration tooling that injects fonts or styles into the document head needs the <head> element to know where to insert content and fails loudly when it is absent.","triggerScenarios":"Running an ng update / schematic (e.g. addFontsToIndex) against an HTML file that has no <head> element — malformed HTML, an HTML fragment, or a file that is not actually an index document.","commonSituations":"A hand-edited or minified index.html missing the head tag; pointing the schematic at a non-HTML file; a workspace with a custom (non-standard) index file; corrupted file encoding breaking the parser.","solutions":["Add a proper <head> element to the target HTML file and re-run the schematic/migration","Verify the schematic is targeting the correct index file (angular.json architect.build.options.index) and that it is a complete HTML document","Manually apply the change the schematic intended (e.g. add font links) if regenerating the file is not possible","Restore a valid index.html from version control or regenerate it with ng new scaffolding as reference"],"exampleFix":"<!-- before -->\n<html><body><app-root></app-root></body></html>\n<!-- after -->\n<html>\n  <head>\n    <title>App</title>\n  </head>\n  <body><app-root></app-root></body>\n</html>","handlingStrategy":"validation","validationCode":"const html = indexBuffer.toString();\nif (!/<head[\\s>]/i.test(html)) {\n  throw new Error(`Cannot modify head: <head> element missing in ${indexPath}. Fix the HTML before running the schematic.`);\n}","typeGuard":"function hasHeadElement(buffer: Buffer): boolean {\n  return /<head[\\s>]/i.test(buffer.toString());\n}","tryCatchPattern":"try {\n  addFontsToIndex(tree, indexPath);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"<head>\")) {\n    console.warn(`${indexPath} has no <head>; skipping font injection. Fix the file manually.`);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Keep index.html a complete, well-formed HTML document with <head> and <body>","Don't minify or hand-strip structural tags from the schematic target file","Verify the index path in angular.json points to the real document","Run ng update on a clean working tree so failed migrations can be reverted"],"tags":["angular","cdk","schematics","html","migration"],"backgroundTag":"missing-html-head-element","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}