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

  1. Do not set the CaptureUnmatchedValues parameter explicitly if you also splat other attributes - let the framework populate it.
  2. If you need to merge, combine the dictionaries in code and pass only the merged dictionary, removing the extra unmatched attributes from markup.
  3. 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

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


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/1f65d4408ae1f384. Report an issue: GitHub.