{"record":{"id":"d78d488603f2f2ef","repo":"dotnet/aspnetcore","slug":"the-type-notfoundpage-fullname-does-not-implemen","errorCode":null,"errorMessage":"The type {NotFoundPage.FullName} does not implement Microsoft.AspNetCore.Components.IComponent.","messagePattern":"The type (.+?) does not implement Microsoft\\.AspNetCore\\.Components\\.IComponent\\.","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/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Routing/Router.cs#L130-L166","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"<!-- before -->\n<Router ... NotFoundPage=\"@typeof(NotFoundModel)\" /> <!-- NotFoundModel is not a component -->\n\n<!-- after -->\n<!-- NotFound.razor: @page \"/404\" -->\n<Router ... NotFoundPage=\"@typeof(NotFound)\" />","handlingStrategy":"type-guard","validationCode":"static Type? ResolveNotFoundPage(Type candidate)\n    => candidate is not null && typeof(IComponent).IsAssignableFrom(candidate) ? candidate : null;","typeGuard":"static bool IsComponentType(Type t) => typeof(IComponent).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["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."],"tags":["blazor","routing","router","notfound","icomponent","type-guard"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}