{"record":{"id":"2d5c76545af24ad9","repo":"dotnet/aspnetcore","slug":"to-support-navigation-locks-gettype-name-must","errorCode":null,"errorMessage":"To support navigation locks, {GetType().Name} must override {nameof(HandleLocationChangingHandlerException)}","messagePattern":"To support navigation locks, (.+?) must override (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Components/Components/src/NavigationManager.cs","lineNumber":560,"sourceCode":"            await handler(context);\n        }\n        catch (OperationCanceledException)\n        {\n            // Ignore exceptions caused by cancellations.\n        }\n        catch (Exception ex)\n        {\n            HandleLocationChangingHandlerException(ex, context);\n        }\n    }\n\n    /// <summary>\n    /// Handles exceptions thrown in location changing handlers.\n    /// </summary>\n    /// <param name=\"ex\">The exception to handle.</param>\n    /// <param name=\"context\">The context passed to the handler.</param>\n    protected virtual void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context)\n        => throw new InvalidOperationException($\"To support navigation locks, {GetType().Name} must override {nameof(HandleLocationChangingHandlerException)}\");\n\n    /// <summary>\n    /// Sets whether navigation is currently locked. If it is, then implementations should not update <see cref=\"Uri\"/> and call\n    /// <see cref=\"NotifyLocationChanged(bool)\"/> until they have first confirmed the navigation by calling\n    /// <see cref=\"NotifyLocationChangingAsync(string, string?, bool)\"/>.\n    /// </summary>\n    /// <param name=\"value\">Whether navigation is currently locked.</param>\n    protected virtual void SetNavigationLockState(bool value)\n        => throw new NotSupportedException($\"To support navigation locks, {GetType().Name} must override {nameof(SetNavigationLockState)}\");\n\n    /// <summary>\n    /// Registers a handler to process incoming navigation events.\n    /// </summary>\n    /// <param name=\"locationChangingHandler\">The handler to process incoming navigation events.</param>\n    /// <returns>An <see cref=\"IDisposable\"/> that can be disposed to unregister the location changing handler.</returns>\n    public IDisposable RegisterLocationChangingHandler(Func<LocationChangingContext, ValueTask> locationChangingHandler)\n    {\n        AssertInitialized();","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/NavigationManager.cs#L542-L578","documentation":"The virtual HandleLocationChangingHandlerException throws InvalidOperationException by default. NavigationManager subclasses that enable navigation locks (RegisterLocationChangingHandler) must override this to decide how to surface handler exceptions, otherwise the lock machinery cannot function.","triggerScenarios":"RegisterLocationChangingHandler is used (activating the navigation-lock path) but the NavigationManager subclass did not override HandleLocationChangingHandlerException; a location-changing handler throws and the default virtual rethrows as InvalidOperationException.","commonSituations":"Custom NavigationManager in a nonstandard host enabling locks without completing the override contract; upgrading to a version that added navigation locks without updating the subclass.","solutions":["Override protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context) in your NavigationManager subclass (log, rethrow, or swallow per your policy).","If you do not need locks, avoid calling RegisterLocationChangingHandler.","Mirror the implementation in the framework's concrete NavigationManager (e.g. RemoteNavigationManager)."],"exampleFix":"// before\npublic class MyNavManager : NavigationManager { /* no override */ }\n\n// after\npublic class MyNavManager : NavigationManager\n{\n    protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context)\n        => logger.LogError(ex, \"Location changing handler failed for {Target}\", context.TargetLocation);\n}","handlingStrategy":"type-guard","validationCode":"static bool SupportsNavigationLockExceptions(NavigationManager nm) =>\n    nm.GetType().GetMethod(\"HandleLocationChangingHandlerException\",\n        BindingFlags.Instance | BindingFlags.NonPublic)?.DeclaringType != typeof(NavigationManager);","typeGuard":"static bool SupportsNavigationLocks(NavigationManager nm) =>\n    nm.GetType().GetMethod(\"HandleLocationChangingHandlerException\",\n        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)?.DeclaringType != typeof(NavigationManager)\n    && nm.GetType().GetMethod(\"SetNavigationLockState\",\n        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)?.DeclaringType != typeof(NavigationManager);","tryCatchPattern":"try { navManager.RegisterLocationChangingHandler(handler); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"HandleLocationChangingHandlerException\"))\n{ logger.LogError(ex, \"NavigationManager does not support locks; skipping registration\"); }","preventionTips":["Override HandleLocationChangingHandlerException in any subclass that enables locks.","Detect lock support before registering handlers in cross-host code.","Keep the override in sync with framework updates."],"tags":["blazor","navigation","navigation-lock","extensibility","subclassing"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}