dotnet/aspnetcore · error · InvalidOperationException

The property '{propertyInfo.Name}' on component type '{targe

Error message

The property '{propertyInfo.Name}' on component type '{targetType.FullName}' cannot be used with '{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}' because it has the wrong type. The property must be assignable from 'Dictionary<string, object>'.

What it means

Thrown by ComponentProperties.ThrowForInvalidCaptureUnmatchedValuesParameterType when the CaptureUnmatchedValues property's type is not assignable from Dictionary<string, object>. The framework instantiates a Dictionary<string, object> to hold unmatched values, so the property type must accept that exact type.

Source

Thrown at src/Components/Components/src/Reflection/ComponentProperties.cs:270

            if (property.GetCustomAttribute<ParameterAttribute>()?.CaptureUnmatchedValues == true)
            {
                propertyNames.Add(property.Name);
            }
        }

        propertyNames.Sort(StringComparer.Ordinal);

        throw new InvalidOperationException(
            $"Multiple properties were found on component type '{targetType.FullName}' with " +
            $"'{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}'. Only a single property " +
            $"per type can use '{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}'. Properties:" + Environment.NewLine +
            string.Join(Environment.NewLine, propertyNames));
    }

    [DoesNotReturn]
    private static void ThrowForInvalidCaptureUnmatchedValuesParameterType(Type targetType, PropertyInfo propertyInfo)
    {
        throw new InvalidOperationException(
            $"The property '{propertyInfo.Name}' on component type '{targetType.FullName}' cannot be used " +
            $"with '{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}' because it has the wrong type. " +
            $"The property must be assignable from 'Dictionary<string, object>'.");
    }

    private sealed class WritersForType
    {
        private const int MaxCachedWriterLookups = 100;
        private readonly Dictionary<string, PropertySetter> _underlyingWriters;
        private readonly ConcurrentDictionary<string, PropertySetter?> _referenceEqualityWritersCache;

        public WritersForType([DynamicallyAccessedMembers(Component)] Type targetType)
        {
            _underlyingWriters = new Dictionary<string, PropertySetter>(StringComparer.OrdinalIgnoreCase);
            _referenceEqualityWritersCache = new ConcurrentDictionary<string, PropertySetter?>(ReferenceEqualityComparer.Instance);

            foreach (var propertyInfo in GetCandidateBindableProperties(targetType))
            {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Change the property type to Dictionary<string, object> (the canonical type).
  2. IDictionary<string, object> also works since Dictionary<string, object> is assignable to it; use that if you only need the interface.
  3. Avoid Dictionary<string, string> or other generic variants - attribute values are object.

Example fix

// before
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, string> Extra { get; set; }

// after
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Extra { get; set; }
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate that a CaptureUnmatchedValues property can hold Dictionary<string, object>.
static bool IsValidCaptureType(Type propertyType)
    => propertyType.IsAssignableFrom(typeof(Dictionary<string, object>));

Type guard

static bool CanHoldAttributeDictionary(Type propertyType)
    => propertyType.IsAssignableFrom(typeof(Dictionary<string, object>));

Prevention

When it happens

Trigger: [Parameter(CaptureUnmatchedValues = true)] on a property whose type cannot hold a Dictionary<string, object>, e.g. Dictionary<string, string>, List<KeyValuePair<string, object>>, or object-typed collections that are not assignable.

Common situations: Using Dictionary<string, string> to capture attributes; a custom collection type; assuming any IDictionary would work when the type parameter differs.

Related errors


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