{"record":{"id":"449b233f9f3c4c1a","repo":"angular/components","slug":"could-not-find-body-element-in-html-file-html","errorCode":null,"errorMessage":"Could not find <body> element in HTML file: ${htmlFileBuffer}","messagePattern":"Could not find <body> element in HTML file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/schematics/utils/html-manipulation.ts","lineNumber":61,"sourceCode":"\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\n/** Adds a class to the body of the document. */\nexport function addBodyClass(host: Tree, htmlFilePath: string, className: string): void {\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  const body = getElementByTagName('body', htmlContent);\n\n  if (!body) {\n    throw Error(`Could not find <body> element in HTML file: ${htmlFileBuffer}`);\n  }\n\n  const classAttribute = body.attrs.find(attribute => attribute.name === 'class');\n\n  if (classAttribute) {\n    const hasClass = classAttribute.value\n      .split(' ')\n      .map(part => part.trim())\n      .includes(className);\n\n    if (!hasClass) {\n      // We have source code location info enabled, and we pre-checked that the element\n      // has attributes, specifically the `class` attribute.\n      const classAttributeLocation = body.sourceCodeLocation!.attrs!['class'];\n      const recordedChange = host\n        .beginUpdate(htmlFilePath)\n        .insertRight(classAttributeLocation.endOffset - 1, ` ${className}`);\n      host.commitUpdate(recordedChange);","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/schematics/utils/html-manipulation.ts#L43-L79","documentation":"Thrown by the CDK schematics helper addBodyClass when the parsed HTML file contains no <body> element. The helper needs the body tag to attach a class attribute, so it throws when the target document lacks one.","triggerScenarios":"Running a schematic that adds a class to <body> against an HTML file without a body tag — a fragment, malformed markup, or a wrong file path configured as the index.","commonSituations":"Custom or generated index.html missing <body>; schematic configured to modify a partial template; file encoding/corruption breaking the HTML parser; running migration on non-app HTML assets.","solutions":["Add a <body> element to the target HTML file and re-run the schematic","Check the index path in angular.json points at the real full-document index.html","Manually add the intended class to <body> if you cannot re-run the tooling","Restore a well-formed index.html from version control"],"exampleFix":"<!-- before -->\n<html><head></head></html>\n<!-- after -->\n<html>\n  <head></head>\n  <body class=\"app-loading\"></body>\n</html>","handlingStrategy":"validation","validationCode":"const html = indexBuffer.toString();\nif (!/<body[\\s>]/i.test(html)) {\n  throw new Error(`Cannot add body class: <body> element missing in ${indexPath}.`);\n}","typeGuard":"function hasBodyElement(buffer: Buffer): boolean {\n  return /<body[\\s>]/i.test(buffer.toString());\n}","tryCatchPattern":"try {\n  addBodyClass(tree, indexPath, 'app-loading');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('<body>')) {\n    console.warn(`${indexPath} has no <body>; skipping class injection.`);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Ensure the target file is a full HTML document with <body>","Confirm the index path configured in angular.json is correct","Validate markup integrity before running update migrations","Keep a scaffolded index.html as reference for valid structure"],"tags":["angular","cdk","schematics","html","migration"],"backgroundTag":"missing-html-body-element","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}