{"record":{"id":"2e61030c20256a44","repo":"dotnet/aspnetcore","slug":"the-type-notfoundpage-fullname-does-not-implemen","errorCode":null,"errorMessage":"The type {NotFoundPage.FullName} does not implement {typeof(IComponent).FullName}.","messagePattern":"The type (.+?) does not implement (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Routing/Router.cs","lineNumber":148,"sourceCode":"        // Found content is mandatory, because even though we could use something like <RouteView ...> as a\n        // reasonable default, if it's not declared explicitly in the template then people will have no way\n        // to discover how to customize this (e.g., to add authorization).\n        if (Found == null)\n        {\n            throw new InvalidOperationException($\"The {nameof(Router)} component requires a value for the parameter {nameof(Found)}.\");\n        }\n\n        if (NotFoundPage != null)\n        {\n#pragma warning disable CS0618 // Type or member is obsolete\n            if (NotFound != null)\n            {\n                throw new InvalidOperationException($\"Setting {nameof(NotFound)} and {nameof(NotFoundPage)} properties simultaneously is not supported. Use either {nameof(NotFound)} or {nameof(NotFoundPage)}.\");\n            }\n#pragma warning restore CS0618 // Type or member is obsolete\n            if (!typeof(IComponent).IsAssignableFrom(NotFoundPage))\n            {\n                throw new InvalidOperationException($\"The type {NotFoundPage.FullName} \" +\n                    $\"does not implement {typeof(IComponent).FullName}.\");\n            }\n\n            var routeAttributes = NotFoundPage.GetCustomAttributes(typeof(RouteAttribute), inherit: true);\n            if (routeAttributes.Length == 0)\n            {\n                throw new InvalidOperationException($\"The type {NotFoundPage.FullName} \" +\n                    $\"does not have a {typeof(RouteAttribute).FullName} applied to it.\");\n            }\n\n            var routeAttribute = (RouteAttribute)routeAttributes[0];\n            if (routeAttribute.Template != null)\n            {\n                _notFoundPageRoute = routeAttribute.Template;\n            }\n        }\n\n        if (!_onNavigateCalled)","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Routing/Router.cs#L130-L166","documentation":"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.","triggerScenarios":"Setting NotFoundPage to a typeof(...) that is a plain class, model, controller, or Razor Page (MVC) rather than a Blazor component.","commonSituations":"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.","solutions":["Verify the type passed to NotFoundPage is a Razor component (has a .razor file or implements IComponent directly).","If the desired 404 page is plain markup, create a new .razor component and reference that.","Filter candidate types with typeof(IComponent).IsAssignableFrom(t) before assigning."],"exampleFix":"// before\n<Router AppAssembly=\"@typeof(Program).Assembly\"\n        NotFoundPage=\"@typeof(NotFoundViewModel)\">  // a POCO, not a component\n// after\n<Router AppAssembly=\"@typeof(Program).Assembly\"\n        NotFoundPage=\"@typeof(NotFound)\">  // NotFound.razor implements IComponent","handlingStrategy":"type-guard","validationCode":"if (notFoundPage is not null && !typeof(IComponent).IsAssignableFrom(notFoundPage))\n    throw new InvalidOperationException($\"{notFoundPage} must implement IComponent.\");","typeGuard":"static bool IsRoutableComponent(Type? t)\n    => t is not null && typeof(IComponent).IsAssignableFrom(t)\n       && t.GetCustomAttributes(typeof(RouteAttribute), inherit: true).Length > 0;","tryCatchPattern":null,"preventionTips":["Only point NotFoundPage at .razor components or classes implementing IComponent.","Keep an inventory of components used as not-found targets.","Add a unit test that asserts the configured NotFoundPage type implements IComponent."],"tags":["blazor","routing","router","notfound","icomponent","invalidoperationexception"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}