PrismLibrary/Prism · error · KeyNotFoundException

No View with the ViewModel

Error message

No View with the ViewModel '{viewModelType.Name}' has been registered

What it means

GetViewModelNavigationKey finds the registered view whose type matches candidates derived from the given ViewModel type and returns the registration name. When no registered view implements/is associated with the ViewModel, it throws KeyNotFoundException. Prism uses this to map a ViewModel type to its view name for navigation.

Solutions

  1. Register the view so its ViewModel association exists: containerRegistry.RegisterForNavigation<MyView, MyViewModel>();
  2. Verify Prism's ViewModel naming convention matches (View name = ViewModel name minus 'ViewModel' suffix) or use [ViewModel(typeof(MyViewModel))] on the view.
  3. Check that the module containing the registration is initialized before navigation.
  4. Confirm the ViewModel type passed is the concrete type used at registration (not a base class).

Example fix

// before
navigationService.NavigateAsync<MyViewModel>(); // no view associated
// after
class App { RegisterTypes(...) { containerRegistry.RegisterForNavigation<MyView, MyViewModel>(); } }
Defensive patterns

Strategy: validation

Validate before calling

var isRegistered = viewRegistryRegistrations.Any(r => r.View == typeof(MyView));
if (!isRegistered)
    containerRegistry.RegisterForNavigation<MyView, MyViewModel>();

Try / catch

try { var key = registry.GetViewModelNavigationKey(typeof(MyViewModel)); }
catch (KeyNotFoundException ex) { logger.LogError(ex, "No view registered for {ViewModel}", typeof(MyViewModel).Name); }

Prevention

When it happens

Trigger: Calling GetViewModelNavigationKey(typeof(MyViewModel)) (directly or via ViewModelLocator-backed navigation) where no view registered in the registry has MyViewModel as its DataContext/ViewModel type.

Common situations: Forgot RegisterForNavigation for the view; ViewModel naming convention mismatch (Prism convention 'MyPage' -> 'MyPageViewModel' broken by renamed types); ViewModel auto-wiring attributes (ViewModelAttribute) missing; view registered only at runtime in another module.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/9ad70f00a6c48247. Report an issue: GitHub.

Appendix: source

Thrown at src/Prism.Core/Mvvm/ViewRegistryBase{TBaseView}.cs:157

    /// Gets the navigation key associated with the specified view model type, or throws an exception if not found.
    /// </summary>
    /// <param name="viewModelType">The type of the view model.</param>
    /// <returns>The navigation key for the view associated with the view model.</returns>
    /// <exception cref="KeyNotFoundException">Thrown if no view is registered for the specified view model.</exception>
    public string GetViewModelNavigationKey(Type viewModelType)
    {
        var registration = Registrations.LastOrDefault(x => x.ViewModel == viewModelType);
        if (registration is not null)
            return registration.Name;

        var candidates = GetCandidates(viewModelType);
        registration = Registrations.LastOrDefault(x => candidates.Any(c => c == x.View));
        if (registration is not null)
        {
            return registration.Name;
        }

        throw new KeyNotFoundException($"No View with the ViewModel '{viewModelType.Name}' has been registered");
    }

    /// <summary>
    /// Gets a collection of registered views that inherit from or implement the specified base type.
    /// </summary>
    /// <param name="baseType">The base type to filter by.</param>
    /// <returns>A collection of matching view registrations.</returns>
    public IEnumerable<ViewRegistration> ViewsOfType(Type baseType) =>
        Registrations.Where(viewRegistration => viewRegistration.View == baseType || baseType.IsAssignableFrom(viewRegistration.View));

    /// <summary>
    /// Checks if a view is registered with the specified name.
    /// </summary>
    /// <param name="name">The name of the view to check.</param>
    /// <returns>True if the view is registered, false otherwise.</returns>
    public bool IsRegistered(string name) =>
        GetRegistration(name) is not null;

View on GitHub (pinned to 358118cd64)