{"record":{"id":"88713b1b4d5a4a01","repo":"dotnet/aspnetcore","slug":"an-exception-occurred-while-dispatching-a-location","errorCode":null,"errorMessage":"An exception occurred while dispatching a location changed event.","messagePattern":"An exception occurred while dispatching a location changed event\\.","errorType":"exception","errorClass":"LocationChangeException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/NavigationManager.cs","lineNumber":403,"sourceCode":"    }\n\n    /// <summary>\n    /// Triggers the <see cref=\"LocationChanged\"/> event with the current URI value.\n    /// </summary>\n    protected void NotifyLocationChanged(bool isInterceptedLink)\n    {\n        try\n        {\n            _locationChanged?.Invoke(\n                this,\n                new LocationChangedEventArgs(_uri!, isInterceptedLink)\n                {\n                    HistoryEntryState = HistoryEntryState\n                });\n        }\n        catch (Exception ex)\n        {\n            throw new LocationChangeException(\"An exception occurred while dispatching a location changed event.\", ex);\n        }\n    }\n\n    /// <summary>\n    /// Notifies the registered handlers of the current location change.\n    /// </summary>\n    /// <param name=\"uri\">The destination URI. This can be absolute, or relative to the base URI.</param>\n    /// <param name=\"state\">The state associated with the target history entry.</param>\n    /// <param name=\"isNavigationIntercepted\">Whether this navigation was intercepted from a link.</param>\n    /// <returns>A <see cref=\"ValueTask{TResult}\"/> representing the completion of the operation. If the result is <see langword=\"true\"/>, the navigation should continue.</returns>\n    protected async ValueTask<bool> NotifyLocationChangingAsync(string uri, string? state, bool isNavigationIntercepted)\n    {\n        _locationChangingCts?.Cancel();\n        _locationChangingCts = null;\n\n        var handlerCount = _locationChangingHandlers.Count;\n\n        if (handlerCount == 0)","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/NavigationManager.cs#L385-L421","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: unguarded handler propagates and surfaces as LocationChangeException\nnavManager.LocationChanged += OnLocationChanged;\nasync void OnLocationChanged(object? s, LocationChangedEventArgs e)\n    => await jsRef.InvokeVoidAsync(\"scroll\", e.Location);\n\n// after: catch handler-local failures so dispatch continues\nnavManager.LocationChanged += OnLocationChanged;\nasync void OnLocationChanged(object? s, LocationChangedEventArgs e)\n{\n    try { await jsRef.InvokeVoidAsync(\"scroll\", e.Location); }\n    catch (Exception ex) { logger.LogWarning(ex, \"LocationChanged handler failed\"); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { navManager.NavigateTo(target, forceLoad: false); }\ncatch (LocationChangeException ex)\n{\n    logger.LogError(ex.InnerException, \"A LocationChanged subscriber threw during navigation to {Target}.\", target);\n}","preventionTips":["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."],"tags":["blazor","routing","events","exception-handling"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}