dotnet/aspnetcore · error · InvalidOperationException

The type does not implement .

Error message

The type {NotFoundPage.FullName} does not implement {typeof(IComponent).FullName}.

What it means

When NotFoundPage is set, Router validates the type implements IComponent, because it will be rendered through the component pipeline (it must be a real routable component, not an arbitrary type). The check runs during SetParametersAsync immediately after the mutual-exclusion check. A non-component type would fail later with an opaque cast, so the type check fails fast.

Solutions

  1. Verify the type passed to NotFoundPage is a Razor component (has a .razor file or implements IComponent directly).
  2. If the desired 404 page is plain markup, create a new .razor component and reference that.
  3. Filter candidate types with typeof(IComponent).IsAssignableFrom(t) before assigning.

Example fix

// before
<Router AppAssembly="@typeof(Program).Assembly"
        NotFoundPage="@typeof(NotFoundViewModel)">  // a POCO, not a component
// after
<Router AppAssembly="@typeof(Program).Assembly"
        NotFoundPage="@typeof(NotFound)">  // NotFound.razor implements IComponent
Defensive patterns

Strategy: type-guard

Validate before calling

if (notFoundPage is not null && !typeof(IComponent).IsAssignableFrom(notFoundPage))
    throw new InvalidOperationException($"{notFoundPage} must implement IComponent.");

Type guard

static bool IsRoutableComponent(Type? t)
    => t is not null && typeof(IComponent).IsAssignableFrom(t)
       && t.GetCustomAttributes(typeof(RouteAttribute), inherit: true).Length > 0;

Prevention

When it happens

Trigger: Setting NotFoundPage to a typeof(...) that is a plain class, model, controller, or Razor Page (MVC) rather than a Blazor component.

Common situations: Pointing NotFoundPage at an MVC view or Razor Pages model by mistake; using a base class or layout type that is not itself a component; refactor that turned a component into a non-component type while the Router reference was unchanged.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/2e61030c20256a44. Report an issue: GitHub.

Appendix: 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 3600ca084e)