dotnet/aspnetcore · error · LocationChangeException
An exception occurred while dispatching a location changed…
Error message
An exception occurred while dispatching a location changed event.
What it means
Thrown by NotifyLocationChanged when any subscriber to the LocationChanged event throws. Rather than letting an unrelated handler exception abort the location-change dispatch, NavigationManager wraps it in a LocationChangeException so callers can distinguish location-event failures from other errors. The original exception is preserved as InnerException.
Solutions
- Inspect LocationChangeException.InnerException to identify the throwing handler and the real error.
- Wrap the body of your LocationChanged handler in try/catch so handler-local failures do not propagate and abort other subscribers.
- Avoid calling NavigationManager.NavigateTo from inside a LocationChanged handler (use a deferred dispatch), and guard access to disposed resources (check IsDisposed or null).
- Move expensive/side-effecting work out of the event handler into a background task that cannot fault the dispatch.
Example fix
// before: unguarded handler propagates and surfaces as LocationChangeException
navManager.LocationChanged += OnLocationChanged;
async void OnLocationChanged(object? s, LocationChangedEventArgs e)
=> await jsRef.InvokeVoidAsync("scroll", e.Location);
// after: catch handler-local failures so dispatch continues
navManager.LocationChanged += OnLocationChanged;
async void OnLocationChanged(object? s, LocationChangedEventArgs e)
{
try { await jsRef.InvokeVoidAsync("scroll", e.Location); }
catch (Exception ex) { logger.LogWarning(ex, "LocationChanged handler failed"); }
} Defensive patterns
Strategy: try-catch
Try / catch
try { navManager.NavigateTo(target, forceLoad: false); }
catch (LocationChangeException ex)
{
logger.LogError(ex.InnerException, "A LocationChanged subscriber threw during navigation to {Target}.", target);
} Prevention
- Subscribe to LocationChanged with a handler that catches its own exceptions.
- Never call NavigateTo from inside a LocationChanged handler; defer via _ = InvokeAsync(() => NavigateTo(...)).
- Check IsDisposed / null before touching JSInterop or DbContext inside the handler.
- Keep handlers short and side-effect free; offload expensive work to a background task.
When it happens
Trigger: A component or service subscribed to NavigationManager.LocationChanged throws synchronously inside the handler (null deref, invalid cast, calling NavigateTo during dispatch, accessing a disposed resource). Triggered on any navigation - link click, NavigateTo, back/forward - that fires LocationChanged.
Common situations: A handler accesses a JSObjectReference after the circuit was lost; a handler calls StateHasChanged on a disposed component; a handler deserializes state that changed schema between versions; a handler performs sync I/O that throws.
Related errors
- ' ' has not been initialized.
- No component found for route
- Setting and properties simultaneously is not supported. Use…
- The custom event ' ' cannot have the same name as its…
- The event ' ' is already registered.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/88713b1b4d5a4a01.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/NavigationManager.cs:403
}
/// <summary>
/// Triggers the <see cref="LocationChanged"/> event with the current URI value.
/// </summary>
protected void NotifyLocationChanged(bool isInterceptedLink)
{
try
{
_locationChanged?.Invoke(
this,
new LocationChangedEventArgs(_uri!, isInterceptedLink)
{
HistoryEntryState = HistoryEntryState
});
}
catch (Exception ex)
{
throw new LocationChangeException("An exception occurred while dispatching a location changed event.", ex);
}
}
/// <summary>
/// Notifies the registered handlers of the current location change.
/// </summary>
/// <param name="uri">The destination URI. This can be absolute, or relative to the base URI.</param>
/// <param name="state">The state associated with the target history entry.</param>
/// <param name="isNavigationIntercepted">Whether this navigation was intercepted from a link.</param>
/// <returns>A <see cref="ValueTask{TResult}"/> representing the completion of the operation. If the result is <see langword="true"/>, the navigation should continue.</returns>
protected async ValueTask<bool> NotifyLocationChangingAsync(string uri, string? state, bool isNavigationIntercepted)
{
_locationChangingCts?.Cancel();
_locationChangingCts = null;
var handlerCount = _locationChangingHandlers.Count;
if (handlerCount == 0)View on GitHub (pinned to 3600ca084e)