dotnet/aspnetcore · error · InvalidOperationException
The property '{parameterName}' on component type '{targetTyp
Error message
The property '{parameterName}' on component type '{targetType.FullName}' cannot be set explicitly when also used to capture unmatched values. Unmatched values: What it means
Thrown by ComponentProperties.ThrowForCaptureUnmatchedValuesConflict when a component has a [Parameter(CaptureUnmatchedValues = true)] property that the user sets explicitly in markup AND there are also unmatched (splat) attributes destined for the same dictionary. The framework refuses to either mutate the user-supplied value or silently copy it.
Source
Thrown at src/Components/Components/src/Reflection/ComponentProperties.cs:240
private static void ThrowForSettingCascadingParameterWithNonCascadingValue(Type targetType, string parameterName)
{
throw new InvalidOperationException(
$"The property '{parameterName}' on component type '{targetType.FullName}' cannot be set " +
$"explicitly because it only accepts cascading values.");
}
[DoesNotReturn]
private static void ThrowForSettingParameterWithCascadingValue(Type targetType, string parameterName)
{
throw new InvalidOperationException(
$"The property '{parameterName}' on component type '{targetType.FullName}' cannot be set " +
$"using a cascading value.");
}
[DoesNotReturn]
private static void ThrowForCaptureUnmatchedValuesConflict(Type targetType, string parameterName, Dictionary<string, object> unmatched)
{
throw new InvalidOperationException(
$"The property '{parameterName}' on component type '{targetType.FullName}' cannot be set explicitly " +
$"when also used to capture unmatched values. Unmatched values:" + Environment.NewLine +
string.Join(Environment.NewLine, unmatched.Keys));
}
[DoesNotReturn]
private static void ThrowForMultipleCaptureUnmatchedValuesParameters([DynamicallyAccessedMembers(Component)] Type targetType)
{
var propertyNames = new List<string>();
foreach (var property in targetType.GetProperties(BindablePropertyFlags))
{
if (property.GetCustomAttribute<ParameterAttribute>()?.CaptureUnmatchedValues == true)
{
propertyNames.Add(property.Name);
}
}
propertyNames.Sort(StringComparer.Ordinal);View on GitHub (pinned to 294cab2f9b)
Solutions
- Do not set the CaptureUnmatchedValues parameter explicitly if you also splat other attributes - let the framework populate it.
- If you need to merge, combine the dictionaries in code and pass only the merged dictionary, removing the extra unmatched attributes from markup.
- Use @attributes="@attrs" on an element inside the component rather than binding the component's own catch-all.
Example fix
// before
<Child Attributes="@attrs" data-foo="bar" />
// after - merge in code, no extra splatted attribute
@code {
private readonly Dictionary<string, object> _merged =
new(attrs) { ["data-foo"] = "bar" };
}
<Child Attributes="@_merged" /> Defensive patterns
Strategy: validation
Validate before calling
// Do not set the CaptureUnmatchedValues parameter explicitly when also splatting attrs.
// Detect the catch-all parameter name to warn callers.
static string? GetCaptureUnmatchedValuesPropertyName(Type componentType)
{
foreach (var p in componentType.GetProperties())
{
if (p.GetCustomAttribute<ParameterAttribute>()?.CaptureUnmatchedValues == true)
return p.Name;
}
return null;
} Type guard
static bool IsCaptureUnmatchedValuesProperty(PropertyInfo p)
=> p.GetCustomAttribute<ParameterAttribute>()?.CaptureUnmatchedValues == true; Prevention
- Never bind the catch-all parameter explicitly while also splatting other attributes.
- Merge attribute dictionaries in code and pass a single dictionary.
- Use @attributes on inner elements instead of binding the component's own catch-all.
- Keep the catch-all parameter name documented so callers avoid direct binding.
When it happens
Trigger: <Child Attributes="@myDict" extra-attr="x" /> where Attributes is the CaptureUnmatchedValues parameter and extra-attr is unmatched.
Common situations: Combining an explicit attributes pass-through with additional splatted attributes on the same element; forwarding @attributes while also binding the catch-all parameter directly.
Related errors
- Multiple properties were found on component type '{targetTyp
- Object of type '{targetType.FullName}' has a property matchi
- The property '{propertyInfo.Name}' on component type '{targe
- The type '{targetType.FullName}' declares a parameter matchi
- Unable to set property '{parameterName}' on object of type '
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/1f65d4408ae1f384.
Report an issue: GitHub.