dotnet/aspnetcore · error · Error

Renderer with ID ' ' is not listening for navigation events

Error message

Renderer with ID '${rendererId}' is not listening for navigation events

What it means

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.

Solutions

  1. Ensure Blazor has fully started (await Blazor.start) before invoking any navigation interop from .NET.
  2. Verify you are not mixing blazor.web.js and blazor.server.js / blazor.webassembly.js bundles on the same page.
  3. Confirm a single render mode is active and the renderer registered before any location-changing listener calls.
  4. Update all Blazor packages and the JS bundle to the same version.

Example fix

// before: calling navigation interop before start completes
await Blazor.start();
// after: ensure the runtime signals readiness; do not call setHasLocationChangingListeners manually
// (this is internal — only the framework should call it)
Defensive patterns

Strategy: validation

Validate before calling

// Do not invoke navigation interop until Blazor is ready
async function whenReady(): Promise<void> {
  await (window as any).Blazor?.start?.();
}
await whenReady();
// then perform navigation calls from .NET

Try / catch

try {
  // navigation call
} catch (e) {
  if (/not listening for navigation/i.test((e as Error).message)) {
    await (window as any).Blazor.start();
    // retry once
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/c7349bbdafe74190. Report an issue: GitHub.

Appendix: source

Thrown at src/Components/Web.JS/src/Services/NavigationManager.ts:69

  });

  if (hasRegisteredNavigationEventListeners) {
    return;
  }

  hasRegisteredNavigationEventListeners = true;
  window.addEventListener('popstate', onPopState);
  currentHistoryIndex = history.state?._index ?? 0;

  attachEnhancedNavigationListener((internalDestinationHref, interceptedLink) => {
    notifyLocationChanged(interceptedLink, internalDestinationHref);
  });
}

function setHasLocationChangingListeners(rendererId: WebRendererId, hasListeners: boolean) {
  const callbacks = navigationCallbacks.get(rendererId);
  if (!callbacks) {
    throw new Error(`Renderer with ID '${rendererId}' is not listening for navigation events`);
  }
  callbacks.hasLocationChangingEventListeners = hasListeners;
}


export function attachToEventDelegator(eventDelegator: EventDelegator): void {
  // We need to respond to clicks on <a> elements *after* the EventDelegator has finished
  // running its simulated bubbling process so that we can respect any preventDefault requests.
  // So instead of registering our own native event, register using the EventDelegator.
  eventDelegator.notifyAfterClick(event => {
    if (!hasInteractiveRouter()) {
      return;
    }

    handleClickForNavigationInterception(event, absoluteInternalHref => {
      performInternalNavigation(absoluteInternalHref, /* interceptedLink */ true, /* replace */ false);
    });
  });

View on GitHub (pinned to 3600ca084e)