{"record":{"id":"c5b91201ebe91121","repo":"dotnet/aspnetcore","slug":"the-component-type-must-implement-typeof-icompone","errorCode":null,"errorMessage":"The component type must implement {typeof(IComponent).FullName}.","messagePattern":"The component type must implement (.+?)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Rendering/RenderTreeBuilder.cs","lineNumber":506,"sourceCode":"\n    /// <summary>\n    /// Appends a frame representing a child component.\n    /// </summary>\n    /// <typeparam name=\"TComponent\">The type of the child component.</typeparam>\n    /// <param name=\"sequence\">An integer that represents the position of the instruction in the source code.</param>\n    public void OpenComponent<[DynamicallyAccessedMembers(Component)] TComponent>(int sequence) where TComponent : notnull, IComponent\n        => OpenComponentUnchecked(sequence, typeof(TComponent));\n\n    /// <summary>\n    /// Appends a frame representing a child component.\n    /// </summary>\n    /// <param name=\"sequence\">An integer that represents the position of the instruction in the source code.</param>\n    /// <param name=\"componentType\">The type of the child component.</param>\n    public void OpenComponent(int sequence, [DynamicallyAccessedMembers(Component)] Type componentType)\n    {\n        if (!typeof(IComponent).IsAssignableFrom(componentType))\n        {\n            throw new ArgumentException($\"The component type must implement {typeof(IComponent).FullName}.\");\n        }\n\n        OpenComponentUnchecked(sequence, componentType);\n    }\n\n    /// <summary>\n    /// Appends a frame representing a component parameter.\n    /// </summary>\n    /// <param name=\"sequence\">An integer that represents the position of the instruction in the source code.</param>\n    /// <param name=\"name\">The name of the attribute.</param>\n    /// <param name=\"value\">The value of the attribute.</param>\n    public void AddComponentParameter(int sequence, string name, object? value)\n    {\n        AssertCanAddComponentParameter();\n        _entries.AppendAttribute(sequence, name, value);\n    }\n\n    /// <summary>","sourceCodeStart":488,"sourceCodeEnd":524,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Rendering/RenderTreeBuilder.cs#L488-L524","documentation":"OpenComponent(int sequence, Type componentType) was called with a type that does not implement IComponent. Components must implement IComponent to be renderable; the builder validates with typeof(IComponent).IsAssignableFrom(componentType).","triggerScenarios":"Passing a POCO, interface, or arbitrary runtime Type into OpenComponent. Reflectively choosing a component type and getting the wrong one. Generic dispatch where TComponent was unconstrained and slipped through.","commonSituations":"Dynamic component rendering where the type comes from configuration/reflection. Migrating a class to be a component but forgetting to implement IComponent. Wrong type passed to a generic <DynamicComponent>. Unit tests with mock types.","solutions":["Verify the type implements IComponent (inherits ComponentBase or implements IComponent directly).","Constrain generic parameters with `where TComponent : IComponent`.","Add a runtime guard before calling OpenComponent: if (!typeof(IComponent).IsAssignableFrom(t)) throw a clearer error."],"exampleFix":"// before\nbuilder.OpenComponent(0, typeof(MyPlainViewModel));\n\n// after\nbuilder.OpenComponent(0, typeof(MyRazorComponent)); // MyRazorComponent : ComponentBase","handlingStrategy":"type-guard","validationCode":"if (!typeof(IComponent).IsAssignableFrom(componentType))\n    throw new ArgumentException($\"{componentType} is not an IComponent.\");\nbuilder.OpenComponent(seq, componentType);","typeGuard":"static bool IsComponentType(Type t) => typeof(IComponent).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Constrain generics: `where TComponent : IComponent`.","For dynamic types, validate IsAssignableFrom before OpenComponent.","Prefer inheriting ComponentBase over implementing IComponent from scratch."],"tags":["blazor","render-tree-builder","component","type-validation","api-misuse"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}