{"record":{"id":"d7d902d4d090f580","repo":"dotnet/aspnetcore","slug":"descriptors-must-be-assigned-a-renderer-id-before","errorCode":null,"errorMessage":"Descriptors must be assigned a renderer ID before getting used as root components","messagePattern":"Descriptors must be assigned a renderer ID before getting used as root components","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Services/WebRootComponentManager.ts","lineNumber":288,"sourceCode":"\n  private refreshRootComponents(components: Iterable<RootComponentInfo>, discoverNewState = false) {\n    const operationsByRendererId = new Map<WebRendererId, RootComponentOperation[]>();\n    const rendererIds: Set<WebRendererId> = new Set<WebRendererId>();\n    for (const component of components) {\n      if (discoverNewState && component.assignedRendererId !== undefined) {\n        // Capture the renderer IDs for the available components to determine the\n        // effective render modes in the document for discovering new persisted state.\n        rendererIds.add(component.assignedRendererId);\n      }\n\n      const operation = this.determinePendingOperation(component);\n      if (!operation) {\n        continue;\n      }\n\n      const rendererId = component.assignedRendererId;\n      if (!rendererId) {\n        throw new Error('Descriptors must be assigned a renderer ID before getting used as root components');\n      }\n\n      let operations = operationsByRendererId.get(rendererId);\n      if (!operations) {\n        operations = [];\n        operationsByRendererId.set(rendererId, operations);\n      }\n\n      operations.push(operation);\n    }\n\n    let serverState = '';\n    let webAssemblyState = '';\n    if (discoverNewState) {\n      for (const rendererId of rendererIds) {\n        if (rendererId === WebRendererId.Server) {\n          // We have server components. Try to discover the persisted state for them\n          // and if there are no updates on this batch, push an empty set of operations","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Services/WebRootComponentManager.ts#L270-L306","documentation":"Thrown inside refreshRootComponents() in WebRootComponentManager.ts:288 when a root component descriptor has a pending operation (add/update/remove) but its assignedRendererId is undefined. Root components are the top-level interactive components discovered from SSR markers; each must be bound to a concrete renderer (Server or WebAssembly) before any operation can be dispatched to that renderer. The manager cannot route an operation to a runtime that was never assigned.","triggerScenarios":"An internal code path calls determinePendingOperation(component) which returns a non-null operation, then reads component.assignedRendererId and finds it falsy. This indicates the descriptor reached the operation-dispatch phase before being activated/assigned a renderer — a framework-internal invariant violation rather than a normal user-actionable flow.","commonSituations":"Almost always an internal Blazor framework bug or a corrupted component-marker state on the page (e.g., hand-edited blazor markers, partially rendered SSR output, or a race between descriptor discovery and renderer attachment). Rarely seen in correctly generated apps; investigate if custom rendering pipeline or third-party SSR manipulation is present.","solutions":["Confirm you are not manually editing or injecting the component markers/blazor: component elements in the DOM that Blazor's SSR emits.","Upgrade to the latest Blazor runtime — this invariant is enforced internally and bugs are fixed across releases.","Reproduce minimally and file an issue with the rendered HTML at the moment of failure so the framework team can trace which descriptor lacked assignment.","Avoid custom RootComponentManager/DescriptorHandler subclasses that bypass the assignedRendererId assignment step."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":"function isRootComponentReady(c: RootComponentInfo): boolean {\n  return c.assignedRendererId !== undefined && c.assignedRendererId !== null;\n}","tryCatchPattern":null,"preventionTips":["Do not hand-edit blazor component markers in the DOM.","Keep server runtime and blazor.web.js versions in sync.","Avoid subclassing RootComponentManager in ways that skip renderer assignment.","Report internal invariant failures with the SSR HTML at failure time."],"tags":["blazor","root-components","renderer","ssr","framework-internal"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}