lepoco/wpfui · error · InvalidOperationException

{nameof(_pageService.GetPage)} returned null

Error message

{nameof(_pageService.GetPage)} returned null

What it means

Thrown by NavigationView.GetPageInstanceFromCache when no IServiceProvider is set but an INavigationViewPageProvider is, and its GetPage(targetPageType) returns null while filling the cache. Cache-layer twin of error 36; same root cause (page provider does not handle the type) surfaced from the cache factory.

Source

Thrown at src/Wpf.Ui/Controls/NavigationView/NavigationView.Navigation.cs:329

        {
            System.Diagnostics.Debug.WriteLine(
                $"Getting {targetPageType} from cache using IServiceProvider."
            );

            return _serviceProvider.GetService(targetPageType)
                ?? throw new InvalidOperationException(
                    $"{nameof(_serviceProvider.GetService)} returned null"
                );
        }

        if (_pageService is not null)
        {
            System.Diagnostics.Debug.WriteLine(
                $"Getting {targetPageType} from cache using INavigationViewPageProvider."
            );

            return _pageService.GetPage(targetPageType)
                ?? throw new InvalidOperationException($"{nameof(_pageService.GetPage)} returned null");
        }

        System.Diagnostics.Debug.WriteLine($"Getting {targetPageType} from cache using reflection.");

        return NavigationViewActivator.CreateInstance(targetPageType)
            ?? throw new InvalidOperationException("Failed to create instance of the page");
    }

    private void ApplyAttachedProperties(INavigationViewItem viewItem, object pageInstance)
    {
        if (pageInstance is FrameworkElement frameworkElement)
        {
            // Store the association between page and navigation item
            PageToNavigationItemDictionary[frameworkElement] = viewItem;

            // Apply HeaderContent if already available
            if (GetHeaderContent(frameworkElement) is { } headerContent)
            {

View on GitHub (pinned to ffebacd610)

Solutions

  1. Make GetPage return a non-null instance for every TargetPageType that may be cached.
  2. Keep the provider's page map in sync with the NavigationViewItems declared in XAML/view-model.
  3. Add logging in GetPage to identify which type returns null.
  4. Alternatively, register pages with an IServiceProvider so the cache uses DI instead.

Example fix

// before
public object? GetPage(Type t) =>
    t == typeof(HomePage) ? new HomePage() : null; // SettingsPage -> throws

// after
public object? GetPage(Type t) => t switch {
    typeof(HomePage) => new HomePage(),
    typeof(SettingsPage) => new SettingsPage(),
    _ => null
};
Defensive patterns

Strategy: validation

Validate before calling

if (_pageService.GetPage(targetPageType) is null)
    throw new InvalidOperationException(
        $"Page provider returned null for {targetPageType}; cannot fill cache.");

Type guard

static bool IsPageKnown(INavigationViewPageProvider p, Type t) => p.GetPage(t) is not null;

Prevention

When it happens

Trigger: NavigationCacheMode enabled for an item, no service provider configured, the INavigationViewPageProvider.GetPage returns null for the target page type when the cache asks for an instance.

Common situations: Custom page provider missing an entry for a page that is now cached; provider's switch/dict out of date after adding a new page; provider returns null on a transient error.

Related errors


AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13). Data as JSON: /api/errors/23bcb38b138cecde. Report an issue: GitHub.