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

  1. Inspect LocationChangeException.InnerException to identify the throwing handler and the real error.
  2. Wrap the body of your LocationChanged handler in try/catch so handler-local failures do not propagate and abort other subscribers.
  3. Avoid calling NavigationManager.NavigateTo from inside a LocationChanged handler (use a deferred dispatch), and guard access to disposed resources (check IsDisposed or null).
  4. 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

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


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)