{"record":{"id":"cc296bec53620fee","repo":"dotnet/aspnetcore","slug":"the-type-targettype-fullname-declares-a-parame","errorCode":null,"errorMessage":"The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public.","messagePattern":"The type '(.+?)' declares a parameter matching the name '(.+?)' that is not public\\. Parameters must be public\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Reflection/ComponentProperties.cs","lineNumber":321,"sourceCode":"                        default:\n                            break;\n                    }\n                }\n\n                // A property cannot accept direct parameters if it's annotated with a cascading value attribute, unless it's a\n                // SupplyParameterFromQueryAttribute. This is to retain backwards compatibility with previous versions of the\n                // SupplyParameterFromQuery feature that did not utilize cascading values, and thus did not have this limitation.\n                var acceptsDirectParameters = parameterAttribute is not null && cascadingParameterAttribute is null or SupplyParameterFromQueryAttribute;\n                var acceptsCascadingParameters = cascadingParameterAttribute is not null;\n                if (!acceptsDirectParameters && !acceptsCascadingParameters)\n                {\n                    continue;\n                }\n\n                var propertyName = propertyInfo.Name;\n                if (parameterAttribute != null && (propertyInfo.SetMethod == null || !propertyInfo.SetMethod.IsPublic))\n                {\n                    throw new InvalidOperationException(\n                        $\"The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public.\");\n                }\n\n                var propertySetter = new PropertySetter(targetType, propertyInfo)\n                {\n                    AcceptsDirectParameters = acceptsDirectParameters,\n                    AcceptsCascadingParameters = acceptsCascadingParameters,\n                };\n\n                if (_underlyingWriters.ContainsKey(propertyName))\n                {\n                    throw new InvalidOperationException(\n                        $\"The type '{targetType.FullName}' declares more than one parameter matching the \" +\n                        $\"name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique.\");\n                }\n\n                _underlyingWriters.Add(propertyName, propertySetter);\n","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Reflection/ComponentProperties.cs#L303-L339","documentation":"Thrown by ComponentProperties.WritersForType constructor when a [Parameter]-decorated property has a setter that is null or non-public. Component parameters require a public setter so the framework can write incoming values via PropertySetter.","triggerScenarios":"Declaring [Parameter] on a get-only property, an init-only property, or a property with a private/protected/internal setter.","commonSituations":"Using { get; init; }, { get; }, or { get; private set; } for a parameter; record positional parameters that produce non-public setters; refactoring that changed setter visibility.","solutions":["Make the setter public: { get; set; }.","If immutability is required, note that Blazor parameters must be publicly settable - restructure rather than hiding the setter.","For records, declare parameter properties with explicit public setters.","Audit [Parameter] properties for non-public setters before runtime."],"exampleFix":"// before\n[Parameter] public int Count { get; init; }\n\n// after\n[Parameter] public int Count { get; set; }","handlingStrategy":"validation","validationCode":"// Audit component types: every [Parameter] property must have a public setter.\nstatic void ValidateComponentParameters(params Type[] componentTypes)\n{\n    foreach (var t in componentTypes)\n    foreach (var p in t.GetProperties(\n        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))\n    {\n        if (p.GetCustomAttribute<ParameterAttribute>() is null) continue;\n        if (p.GetSetMethod(nonPublic: false) is null)\n            throw new InvalidOperationException(\n                $\"{t.FullName}.{p.Name} has [Parameter] but no public setter.\");\n    }\n}","typeGuard":"static bool HasPublicSetter(PropertyInfo p) => p.GetSetMethod(nonPublic: false) is not null;","tryCatchPattern":null,"preventionTips":["Use { get; set; } for all [Parameter] properties.","Avoid { get; init; }, { get; }, and { get; private set; } for parameters.","For records, declare parameters with explicit public setters.","Include a setter-visibility audit in your component build/test step."],"tags":["blazor","parameters","reflection","attributes","visibility","rendering"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}