dotnet/aspnetcore · error
Interop methods are already registered for renderer ${render
Error message
Interop methods are already registered for renderer ${rendererId} What it means
Thrown by attachWebRendererInterop when interopMethodsByRenderer already has an entry for the given rendererId. Each renderer (Server=1, WebAssembly=2) may register its interop methods exactly once; a duplicate attach indicates the renderer initialized twice without a corresponding detach.
Source
Thrown at src/Components/Web.JS/src/Rendering/WebRendererInteropMethods.ts:27
const rendererAttachedListeners: ((browserRendererId: number) => void)[] = [];
const rendererByIdResolverMap: Map<number, [() => void | undefined, Promise<void> | undefined]> = new Map();
export function attachRendererIdResolver(rendererId: number, resolver: () => void | undefined, promise: Promise<void> | undefined) {
rendererByIdResolverMap.set(rendererId, [resolver, promise]);
}
export function getRendererAttachedPromise(rendererId: number): Promise<void> | undefined {
return rendererByIdResolverMap.get(rendererId)?.[1];
}
export function attachWebRendererInterop(
rendererId: number,
interopMethods: DotNet.DotNetObject,
jsComponentParameters?: JSComponentParametersByIdentifier,
jsComponentInitializers?: JSComponentIdentifiersByInitializer,
): void {
if (interopMethodsByRenderer.has(rendererId)) {
throw new Error(`Interop methods are already registered for renderer ${rendererId}`);
}
interopMethodsByRenderer.set(rendererId, interopMethods);
if (jsComponentParameters && jsComponentInitializers && Object.keys(jsComponentParameters).length > 0) {
const manager = getInteropMethods(rendererId);
enableJSRootComponents(rendererId, manager, jsComponentParameters, jsComponentInitializers);
}
rendererByIdResolverMap.get(rendererId)?.[0]?.();
invokeRendererAttachedListeners(rendererId);
}
export function detachWebRendererInterop(rendererId: number): DotNet.DotNetObject {
const interopMethods = interopMethodsByRenderer.get(rendererId);
if (!interopMethods) {
throw new Error(`Interop methods are not registered for renderer ${rendererId}`);View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure detachWebRendererInterop runs (e.g. on connection close) before re-attaching — the framework does this in onclose.
- Avoid calling Blazor.start() more than once; reload the page instead.
- Guard custom attach code with isRendererAttached(rendererId) before calling attach.
Example fix
// before
attachWebRendererInterop(WebRendererId.Server, methods); // second attach throws
// after
if (!isRendererAttached(WebRendererId.Server)) {
attachWebRendererInterop(WebRendererId.Server, methods);
} Defensive patterns
Strategy: validation
Validate before calling
// Guard attach with isRendererAttached.
import { attachWebRendererInterop, isRendererAttached } from './WebRendererInteropMethods';
if (!isRendererAttached(WebRendererId.Server)) {
attachWebRendererInterop(WebRendererId.Server, methods);
} Prevention
- Always detach (detachWebRendererInterop) before re-attaching a renderer.
- Call Blazor.start() only once; reload to reinitialize.
- Guard custom attach paths with isRendererAttached().
When it happens
Trigger: attachWebRendererInterop called twice for the same WebRendererId without an intervening detachWebRendererInterop — e.g. a circuit restart that re-attaches before the previous attach was detached, or double Blazor boot.
Common situations: Reconnection flows racing with attach; HMR re-initializing the renderer; calling Blazor.start() twice; custom hosts that re-attach on route change.
Related errors
- Interop methods are not registered for renderer ${rendererId
- No interop methods are registered for renderer ${rendererId}
- Renderer with ID '${rendererId}' is not listening for naviga
- No renderer has been initialized.
- Cannot supply a component of type '{componentType}' because
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/26b1d5b1841d75fb.
Report an issue: GitHub.