dotnet/aspnetcore · error · InvalidOperationException
The type ' ' declares a parameter matching the name ' '…
Error message
The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public. What it means
WritersForType constructor in ComponentProperties requires every [Parameter]-annotated property to have a public setter so the framework can assign incoming values. If propertyInfo.SetMethod is null (no setter) or not public, the PropertySetter cannot be built and the type cache throws during first use of the component. This is the component-parameter analogue of the persistent-service setter check.
Solutions
- Make the setter public: [Parameter] public int Count { get; set; }.
- For init patterns use 'public init'.
- If encapsulation is required, perform validation in OnParametersSet or in a public setter body rather than hiding the setter.
Example fix
// before
[Parameter]
public int Count { get; private set; }
// after
[Parameter]
public int Count { get; set; } Defensive patterns
Strategy: type-guard
Type guard
static bool HasPublicParameterSetter(PropertyInfo p)
=> p.GetCustomAttribute<ParameterAttribute>() != null
&& p.SetMethod != null && p.SetMethod.IsPublic;
foreach (var p in typeof(MyComponent).GetProperties())
{
if (p.GetCustomAttribute<ParameterAttribute>() != null)
Assert.True(HasPublicParameterSetter(p));
} Prevention
- Make [Parameter] property setters public.
- Add a reflection-based unit test asserting public setters on all parameters.
- Validate in OnParametersSet rather than hiding the setter.
When it happens
Trigger: Declaring [Parameter] on a property with a private/protected/internal setter, an init-only setter that is non-public, or no setter at all. The error surfaces when the component is first rendered or its writers cache is built.
Common situations: Encapsulating a parameter's value with a private setter to enforce validation, while still annotating it [Parameter]. Using { get; } without a setter. Migrating a property to a parameter without exposing the setter.
Related errors
- Object of type ' ' does not have a property matching the…
- Unable to set property
- Multiple properties were found on component type
- Object of type ' ' has a property matching the name ' '…
- The property ' ' on component type ' ' cannot be set…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/cc296bec53620fee.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/Reflection/ComponentProperties.cs:321
default:
break;
}
}
// A property cannot accept direct parameters if it's annotated with a cascading value attribute, unless it's a
// SupplyParameterFromQueryAttribute. This is to retain backwards compatibility with previous versions of the
// SupplyParameterFromQuery feature that did not utilize cascading values, and thus did not have this limitation.
var acceptsDirectParameters = parameterAttribute is not null && cascadingParameterAttribute is null or SupplyParameterFromQueryAttribute;
var acceptsCascadingParameters = cascadingParameterAttribute is not null;
if (!acceptsDirectParameters && !acceptsCascadingParameters)
{
continue;
}
var propertyName = propertyInfo.Name;
if (parameterAttribute != null && (propertyInfo.SetMethod == null || !propertyInfo.SetMethod.IsPublic))
{
throw new InvalidOperationException(
$"The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public.");
}
var propertySetter = new PropertySetter(targetType, propertyInfo)
{
AcceptsDirectParameters = acceptsDirectParameters,
AcceptsCascadingParameters = acceptsCascadingParameters,
};
if (_underlyingWriters.ContainsKey(propertyName))
{
throw new InvalidOperationException(
$"The type '{targetType.FullName}' declares more than one parameter matching the " +
$"name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique.");
}
_underlyingWriters.Add(propertyName, propertySetter);
View on GitHub (pinned to 3600ca084e)