dotnet/aspnetcore · error · InvalidOperationException
The type {NotFoundPage.FullName} does not implement Microsof
Error message
The type {NotFoundPage.FullName} does not implement Microsoft.AspNetCore.Components.IComponent. What it means
Thrown in Router.SetParametersAsync when NotFoundPage is set to a type that does not implement IComponent. The Router renders NotFoundPage as a routed page component (it looks up its [Route] template and renders it), so it must be a real Blazor component, not an arbitrary type.
Source
Thrown at src/Components/Components/src/Routing/Router.cs:148
// Found content is mandatory, because even though we could use something like <RouteView ...> as a
// reasonable default, if it's not declared explicitly in the template then people will have no way
// to discover how to customize this (e.g., to add authorization).
if (Found == null)
{
throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(Found)}.");
}
if (NotFoundPage != null)
{
#pragma warning disable CS0618 // Type or member is obsolete
if (NotFound != null)
{
throw new InvalidOperationException($"Setting {nameof(NotFound)} and {nameof(NotFoundPage)} properties simultaneously is not supported. Use either {nameof(NotFound)} or {nameof(NotFoundPage)}.");
}
#pragma warning restore CS0618 // Type or member is obsolete
if (!typeof(IComponent).IsAssignableFrom(NotFoundPage))
{
throw new InvalidOperationException($"The type {NotFoundPage.FullName} " +
$"does not implement {typeof(IComponent).FullName}.");
}
var routeAttributes = NotFoundPage.GetCustomAttributes(typeof(RouteAttribute), inherit: true);
if (routeAttributes.Length == 0)
{
throw new InvalidOperationException($"The type {NotFoundPage.FullName} " +
$"does not have a {typeof(RouteAttribute).FullName} applied to it.");
}
var routeAttribute = (RouteAttribute)routeAttributes[0];
if (routeAttribute.Template != null)
{
_notFoundPageRoute = routeAttribute.Template;
}
}
if (!_onNavigateCalled)View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the type passed to NotFoundPage is a Blazor component (a .razor file with @page, which derives from ComponentBase).
- Verify typeof(IComponent).IsAssignableFrom(NotFoundPage) at the call site or in a test.
- If the type is meant to be the 404 page, make it a component with @page "/404" (or similar).
Example fix
<!-- before --> <Router ... NotFoundPage="@typeof(NotFoundModel)" /> <!-- NotFoundModel is not a component --> <!-- after --> <!-- NotFound.razor: @page "/404" --> <Router ... NotFoundPage="@typeof(NotFound)" />
Defensive patterns
Strategy: type-guard
Validate before calling
static Type? ResolveNotFoundPage(Type candidate)
=> candidate is not null && typeof(IComponent).IsAssignableFrom(candidate) ? candidate : null; Type guard
static bool IsComponentType(Type t) => typeof(IComponent).IsAssignableFrom(t);
Prevention
- Pass only a Blazor component type to NotFoundPage.
- Verify typeof(IComponent).IsAssignableFrom(NotFoundPage) before binding.
- Make the 404 page a .razor component deriving from ComponentBase.
When it happens
Trigger: Setting NotFoundPage="@typeof(SomeClass)" where SomeClass does not implement IComponent (e.g., a plain page model, a static HTML helper, or a Razor class that is not a component).
Common situations: Pointing NotFoundPage at a layout type or a non-component Razor file; a refactor where the 404 page lost its @inherits ComponentBase; confusion between a component and a plain Razor view.
Related errors
- The value must implement IComponent.
- Setting NotFound and NotFoundPage properties simultaneously
- The type {NotFoundPage.FullName} does not have a Microsoft.A
- The type {context.Handler.FullName} does not implement Micro
- The Router component requires a value for the parameter AppA
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/d78d488603f2f2ef.
Report an issue: GitHub.