lepoco/wpfui · error · InvalidOperationException

{nameof(_serviceProvider)}.{nameof(_serviceProvider.GetServi

Error message

{nameof(_serviceProvider)}.{nameof(_serviceProvider.GetService)} returned null for type {viewItem.TargetPageType}.

What it means

Thrown by NavigationView.GetNavigationItemInstance when an IServiceProvider is configured but GetService(TargetPageType) returns null — i.e. the page type is not registered with the DI container. The navigation system prefers the service provider, so a missing registration aborts rather than falling back to reflection.

Source

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

        if (Journal.Count > 0)
        {
            Debug.WriteLineIf(EnableDebugMessages, $"JOURNAL LAST ELEMENT {Journal[^1]}");
        }
    }

    private object GetNavigationItemInstance(INavigationViewItem viewItem)
    {
        if (viewItem.TargetPageType is null)
        {
            throw new InvalidOperationException(
                $"The {nameof(viewItem)}.{nameof(viewItem.TargetPageType)} property cannot be null."
            );
        }

        if (_serviceProvider is not null)
        {
            return _serviceProvider.GetService(viewItem.TargetPageType)
                ?? throw new InvalidOperationException(
                    $"{nameof(_serviceProvider)}.{nameof(_serviceProvider.GetService)} returned null for type {viewItem.TargetPageType}."
                );
        }

        if (_pageService is not null)
        {
            return _pageService.GetPage(viewItem.TargetPageType)
                ?? throw new InvalidOperationException(
                    $"{nameof(_pageService)}.{nameof(_pageService.GetPage)} returned null for type {viewItem.TargetPageType}."
                );
        }

        return _cache.Remember(
                viewItem.TargetPageType,
                viewItem.NavigationCacheMode,
                ComputeCachedNavigationInstance
            )
            ?? throw new InvalidOperationException(

View on GitHub (pinned to ffebacd610)

Solutions

  1. Register the page type in the service provider: services.AddTransient<MyPage>() (or AddSingleton/Scoped as appropriate).
  2. Ensure you register the exact Type returned by TargetPageType (concrete type, not just an interface).
  3. If using assembly-scanned registration, verify the page assembly is included in the scan.
  4. Alternatively, do not pass an IServiceProvider and let NavigationView use IPageProvider or reflection.

Example fix

// before
services.AddSingleton<INavigationViewPageProvider, PageProvider>();
// MyPage not registered -> throws

// after
services.AddTransient<MyPage>();
services.AddSingleton<INavigationViewPageProvider, PageProvider>();
Defensive patterns

Strategy: validation

Validate before calling

if (_serviceProvider.GetService(viewItem.TargetPageType) is null)
    throw new InvalidOperationException(
        $"Page {viewItem.TargetPageType} is not registered in the service provider.");

Type guard

static bool IsPageRegistered(IServiceProvider sp, Type t) => sp.GetService(t) is not null;

Prevention

When it happens

Trigger: Navigating to a NavigationViewItem whose TargetPageType has not been registered in the IServiceProvider passed to NavigationView; the page type was registered under a different interface than the concrete type; transient/scoped registration misconfiguration.

Common situations: Forgetting services.AddSingleton<MyPage>() in the DI setup; registering the page against an interface but navigating to the concrete type; conditional registration where the page was not added in the current composition root.

Related errors


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