{"record":{"id":"656e88cc02ea6292","repo":"dotnet/aspnetcore","slug":"object-of-type-targettype-fullname-has-a-prope","errorCode":null,"errorMessage":"Object of type '{targetType.FullName}' has a property matching the name '{parameterName}', but it does not have [Parameter], [CascadingParameter], or any other parameter-supplying attribute.","messagePattern":"Object of type '(.+?)' has a property matching the name '(.+?)', but it does not have \\[Parameter\\], \\[CascadingParameter\\], or any other parameter-supplying attribute\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Reflection/ComponentProperties.cs","lineNumber":202,"sourceCode":"        }\n    }\n\n    internal static IEnumerable<PropertyInfo> GetCandidateBindableProperties([DynamicallyAccessedMembers(Component)] Type targetType)\n        => MemberAssignment.GetPropertiesIncludingInherited(targetType, BindablePropertyFlags);\n\n    [DoesNotReturn]\n    private static void ThrowForUnknownIncomingParameterName([DynamicallyAccessedMembers(Component)] Type targetType,\n        string parameterName)\n    {\n        // We know we're going to throw by this stage, so it doesn't matter that the following\n        // reflection code will be slow. We're just trying to help developers see what they did wrong.\n        var propertyInfo = targetType.GetProperty(parameterName, BindablePropertyFlags);\n        if (propertyInfo != null)\n        {\n            if (!propertyInfo.IsDefined(typeof(ParameterAttribute)) &&\n                !propertyInfo.GetCustomAttributes().OfType<CascadingParameterAttributeBase>().Any())\n            {\n                throw new InvalidOperationException(\n                    $\"Object of type '{targetType.FullName}' has a property matching the name '{parameterName}', \" +\n                    $\"but it does not have [Parameter], [CascadingParameter], or any other parameter-supplying attribute.\");\n            }\n            else\n            {\n                // This should not happen\n                throw new InvalidOperationException(\n                    $\"No writer was cached for the property '{propertyInfo.Name}' on type '{targetType.FullName}'.\");\n            }\n        }\n        else\n        {\n            throw new InvalidOperationException(\n                $\"Object of type '{targetType.FullName}' does not have a property \" +\n                $\"matching the name '{parameterName}'.\");\n        }\n    }\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Reflection/ComponentProperties.cs#L184-L220","documentation":"ThrowForUnknownIncomingParameterName fires when the parameter-binding cache cannot find a writer for an incoming parameter name, but reflection then locates a property with that name on the component type. If that property lacks both [Parameter] (or ParameterAttribute) and any CascadingParameterAttributeBase, the framework cannot route a value to it; Blazor parameters must be explicitly marked. The error tells the developer which attribute is missing.","triggerScenarios":"Passing a parameter in markup or via RenderTreeBuilder to a property that exists on the component but is not annotated with [Parameter] or [CascadingParameter]. Forgetting the [Parameter] attribute on a property intended to receive values. Typing a parameter name that coincidentally matches a non-parameter public property.","commonSituations":"Creating a component, adding a public property meant to be a parameter, but forgetting [Parameter]. Renaming an actual parameter and leaving a stale property without the attribute. Passing arbitrary attributes that collide with helper/internal property names.","solutions":["Add [Parameter] to the property that should receive the value.","If the property is meant to receive a cascading value, add [CascadingParameter] (or a derived attribute) and pass it as a cascading value, not a direct parameter.","If the property is not intended as a parameter, rename or remove the incoming parameter from markup so it does not collide."],"exampleFix":"// before\n// Counter.razor.cs\npublic int Count { get; set; }\n// usage\n<Counter Count=\"5\" />\n\n// after\n[Parameter]\npublic int Count { get; set; }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsBlazorParameter(PropertyInfo p)\n    => p.GetCustomAttribute<ParameterAttribute>() != null\n       || p.GetCustomAttributes().OfType<CascadingParameterAttributeBase>().Any();\n\n// Before binding, ensure the target property is annotated:\nif (!IsBlazorParameter(typeof(MyComponent).GetProperty(\"Foo\")!))\n    throw new InvalidOperationException(\"Foo is not a parameter.\");","tryCatchPattern":null,"preventionTips":["Always annotate bindable properties with [Parameter] or [CascadingParameter].","Use analyzers/source generators that flag un-annotated properties passed in markup.","Review component API surface when adding new public properties."],"tags":["blazor","parameters","reflection","attributes"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}