{"record":{"id":"c7349bbdafe74190","repo":"dotnet/aspnetcore","slug":"renderer-with-id-rendererid-is-not-listening","errorCode":null,"errorMessage":"Renderer with ID '${rendererId}' is not listening for navigation events","messagePattern":"Renderer with ID '(.+?)' is not listening for navigation events","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Services/NavigationManager.ts","lineNumber":69,"sourceCode":"  });\n\n  if (hasRegisteredNavigationEventListeners) {\n    return;\n  }\n\n  hasRegisteredNavigationEventListeners = true;\n  window.addEventListener('popstate', onPopState);\n  currentHistoryIndex = history.state?._index ?? 0;\n\n  attachEnhancedNavigationListener((internalDestinationHref, interceptedLink) => {\n    notifyLocationChanged(interceptedLink, internalDestinationHref);\n  });\n}\n\nfunction setHasLocationChangingListeners(rendererId: WebRendererId, hasListeners: boolean) {\n  const callbacks = navigationCallbacks.get(rendererId);\n  if (!callbacks) {\n    throw new Error(`Renderer with ID '${rendererId}' is not listening for navigation events`);\n  }\n  callbacks.hasLocationChangingEventListeners = hasListeners;\n}\n\n\nexport function attachToEventDelegator(eventDelegator: EventDelegator): void {\n  // We need to respond to clicks on <a> elements *after* the EventDelegator has finished\n  // running its simulated bubbling process so that we can respect any preventDefault requests.\n  // So instead of registering our own native event, register using the EventDelegator.\n  eventDelegator.notifyAfterClick(event => {\n    if (!hasInteractiveRouter()) {\n      return;\n    }\n\n    handleClickForNavigationInterception(event, absoluteInternalHref => {\n      performInternalNavigation(absoluteInternalHref, /* interceptedLink */ true, /* replace */ false);\n    });\n  });","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Services/NavigationManager.ts#L51-L87","documentation":"Blazor's NavigationManager tracks per-renderer navigation callbacks in a map keyed by WebRendererId. setHasLocationChangingListeners is called by a renderer to toggle whether it has location-changing listeners; if no entry exists in navigationCallbacks for that rendererId it means the renderer never registered itself (via notifyLocationChanged / attachToEventDelegator path), so updating its listener flag is a programming error rather than a runtime condition.","triggerScenarios":"Thrown at line 69 when setHasLocationChangingListeners(rendererId, ...) is invoked but navigationCallbacks.get(rendererId) returns undefined. Happens if a renderer tries to set location-changing listeners before its callbacks were registered with the NavigationManager.","commonSituations":"Custom interop that calls Blazor navigation APIs out of order; a misconfigured multi-renderer setup; version skew where a renderer ID is passed that the JS runtime does not recognize; calling navigation interop before Blazor.start completes.","solutions":["Ensure Blazor has fully started (await Blazor.start) before invoking any navigation interop from .NET.","Verify you are not mixing blazor.web.js and blazor.server.js / blazor.webassembly.js bundles on the same page.","Confirm a single render mode is active and the renderer registered before any location-changing listener calls.","Update all Blazor packages and the JS bundle to the same version."],"exampleFix":"// before: calling navigation interop before start completes\nawait Blazor.start();\n// after: ensure the runtime signals readiness; do not call setHasLocationChangingListeners manually\n// (this is internal — only the framework should call it)","handlingStrategy":"validation","validationCode":"// Do not invoke navigation interop until Blazor is ready\nasync function whenReady(): Promise<void> {\n  await (window as any).Blazor?.start?.();\n}\nawait whenReady();\n// then perform navigation calls from .NET","typeGuard":null,"tryCatchPattern":"try {\n  // navigation call\n} catch (e) {\n  if (/not listening for navigation/i.test((e as Error).message)) {\n    await (window as any).Blazor.start();\n    // retry once\n  } else throw e;\n}","preventionTips":["Await Blazor.start before any navigation interop.","Use a single Blazor JS bundle per page (web.js, not server.js + webassembly.js).","Keep a single active render mode to avoid renderer-ID mismatches.","Align all Blazor package versions."],"tags":["blazor","navigation","renderer","interop","initialization-order"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}