lepoco/wpfui · error · InvalidOperationException
{nameof(_serviceProvider.GetService)} returned null
Error message
{nameof(_serviceProvider.GetService)} returned null What it means
Thrown by NavigationView.GetPageInstanceFromCache (the cache-fill path) when an IServiceProvider is configured but GetService(targetPageType) returns null. This is the cache-layer twin of error 35: same root cause (page not registered with DI) but surfaced while populating the navigation cache rather than during the primary resolution attempt. Note the message is shorter and lacks the type name, which can make diagnosis harder.
Source
Thrown at src/Wpf.Ui/Controls/NavigationView/NavigationView.Navigation.cs:317
object? ComputeCachedNavigationInstance() => GetPageInstanceFromCache(viewItem.TargetPageType);
}
private object? GetPageInstanceFromCache(Type? targetPageType)
{
if (targetPageType is null)
{
return default;
}
if (_serviceProvider is not null)
{
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");View on GitHub (pinned to ffebacd610)
Solutions
- Register the page type with the IServiceProvider: services.AddTransient<MyPage>().
- Verify the registered type matches TargetPageType exactly.
- If using assembly scanning, ensure the page assembly is scanned.
- Alternatively disable caching for that item or supply a page provider.
Example fix
// before builder.Services.AddSingleton<MainWindow>(); // MyPage missing -> throws on cached navigate // after builder.Services.AddTransient<MyPage>();
Defensive patterns
Strategy: validation
Validate before calling
if (_serviceProvider.GetService(targetPageType) is null)
throw new InvalidOperationException(
$"Page {targetPageType} not registered; cache cannot fill it."); Type guard
static bool IsPageRegistered(IServiceProvider sp, Type t) => sp.GetService(t) is not null;
Prevention
- Register every page type with the DI container, especially cached ones.
- Verify the registered type exactly equals TargetPageType.
- Consider disabling NavigationCacheMode for pages not in DI.
When it happens
Trigger: Cache mode is active for a NavigationViewItem, GetNavigationItemInstance delegated to GetPageInstanceFromCache, an IServiceProvider is set, and GetService returns null for the target page type.
Common situations: Page type missing from DI while NavigationCacheMode is enabled (so the cache factory path runs); transient registration not registered; composition root conditionally omitted the page.
Related errors
- {nameof(_serviceProvider)}.{nameof(_serviceProvider.GetServi
- {nameof(_pageService.GetPage)} returned null
- The {nameof(viewItem)}.{nameof(viewItem.TargetPageType)} pro
- {nameof(_pageService)}.{nameof(_pageService.GetPage)} return
- Unable to get or create instance of {viewItem.TargetPageType
AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13).
Data as JSON: /api/errors/ac7219774aa31529.
Report an issue: GitHub.