{"record":{"id":"98f58293f258a91f","repo":"dotnet/aspnetcore","slug":"root-components-cannot-be-marked-as-interactive-t","errorCode":null,"errorMessage":"Root components cannot be marked as interactive. The <html> element must be rendered statically so that scripts are not evaluated multiple times.","messagePattern":"Root components cannot be marked as interactive\\. The <html> element must be rendered statically so that scripts are not evaluated multiple times\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts","lineNumber":181,"sourceCode":"    } else {\n      return;\n    }\n  }\n}\n\nfunction parseCommentPayload(json: string): ServerComponentMarker | WebAssemblyComponentMarker | AutoComponentMarker {\n  const payload = JSON.parse(json);\n  const { type } = payload;\n  if (type !== 'server' && type !== 'webassembly' && type !== 'auto') {\n    throw new Error(`Invalid component type '${type}'.`);\n  }\n\n  return payload;\n}\n\nfunction assertNotDirectlyOnDocument(marker: Node) {\n  if (marker.parentNode instanceof Document) {\n    throw new Error('Root components cannot be marked as interactive. The <html> element must be rendered statically so that scripts are not evaluated multiple times.');\n  }\n}\n\nfunction getComponentEndComment(payload: ComponentMarker, start: Comment, iterator: ComponentCommentIterator): Comment | undefined {\n  const { prerenderId } = payload;\n  if (!prerenderId) {\n    return undefined;\n  }\n\n  while (iterator.next() && iterator.currentElement) {\n    const node = iterator.currentElement;\n    if (node.nodeType !== Node.COMMENT_NODE) {\n      continue;\n    }\n    if (!node.textContent) {\n      continue;\n    }\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts#L163-L199","documentation":"Thrown by assertNotDirectlyOnDocument when a component marker's parent node is the Document itself (i.e. the marker is a direct child of the document root, such as attached to <html>). Root components attached directly to the document would make <html> interactive, causing scripts to evaluate multiple times. The guard forbids interactive root components on the document root.","triggerScenarios":"Placing a Blazor interactive root component marker such that its parent is document; rendering a component whose host is the <html> element; SSR output that puts the component comment directly under document.","commonSituations":"Trying to make the entire page (including <head> scripts) interactive; misconfigured App.razor/_Host that attaches the root at document level; a custom layout that targets document.documentElement.","solutions":["Attach interactive root components to a descendant element (e.g. <div id=\"app\">), never to <html> or document directly.","Keep <html> and <head> statically rendered.","Adjust the host page so the component comment lives under <body> or deeper.","If global interactivity is needed, scope it to <body> rather than document."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function assertNotDocumentRoot(marker: Node) {\n  if (marker.parentNode instanceof Document || marker.parentNode === document.documentElement) {\n    throw new Error('Do not attach interactive root components to <html> or document.');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always scope interactive components under <body> or deeper elements.","Keep <html> and <head> statically rendered.","Review App.razor/_Host to ensure the component host is a body descendant."],"tags":["blazor","prerendering","markers","ssr","document-root"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}