dotnet/aspnetcore · error · InvalidOperationException

The property ' ' on component type ' ' cannot be set…

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

ThrowForCaptureUnmatchedValuesConflict fires when a single property is annotated with [Parameter(CaptureUnmatchedValues = true)] (making it the unmatched-attributes sink) AND the framework is also asked to set that same property explicitly with a direct value. The sink property cannot simultaneously hold explicit assigned state and unmatched attributes; Blazor rejects the conflicting usage to prevent ambiguous data.

Solutions

  1. Do not pass the capture-sink property name explicitly in markup; let it receive only unmatched attributes.
  2. If you need to set that dictionary explicitly, remove CaptureUnmatchedValues = true and handle unmatched attributes separately.
  3. Rename the sink property to avoid collision with any explicitly-supplied parameter name.

Example fix

// before
// Component: [Parameter(CaptureUnmatchedValues = true)]
//            public Dictionary<string,object>? Attributes { get; set; }
<MyComponent Attributes="@(new Dictionary<string,object>())" />

// after
<MyComponent class="btn" data-foo="bar" /> // unmatched only; Attributes auto-populated
Defensive patterns

Strategy: validation

Validate before calling

// Detect capture-sink collision before rendering.
var sinkProp = typeof(MyComponent).GetProperties()
    .FirstOrDefault(p => p.GetCustomAttribute<ParameterAttribute>()?.CaptureUnmatchedValues == true);
if (sinkProp != null && suppliedParameterNames.Contains(sinkProp.Name))
    throw new InvalidOperationException($"Do not pass '{sinkProp.Name}' explicitly; it captures unmatched values.");

Prevention

When it happens

Trigger: Declaring [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> Attributes { get; set; } and then in markup writing <MyComponent Attributes="..." /> (passing Attributes explicitly). The framework detects both an explicit assignment target and the unmatched-capture role on the same property.

Common situations: Adding a splat-attributes sink named 'Attributes' and then accidentally also setting 'Attributes' as a regular parameter in markup. Component libraries whose public surface exposes the capture property by a name consumers also pass.

Related errors


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

Appendix: 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 3600ca084e)