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
- Change the property type to Dictionary<string, object> (the canonical type).
- IDictionary<string, object> also works since Dictionary<string, object> is assignable to it; use that if you only need the interface.
- 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
- Type catch-all parameters as Dictionary<string, object> (or IDictionary<string, object>).
- Never use Dictionary<string, string> or unrelated collection types for unmatched attributes.
- Add a build-time check that the property type is assignable from Dictionary<string, object>.
- Remember attribute values are object, not string.
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
- Unable to set property '{parameterName}' on object of type '
- The property '{parameterName}' on component type '{targetTyp
- Multiple properties were found on component type '{targetTyp
- Object of type '{targetType.FullName}' has a property matchi
- Object of type '{targetType.FullName}' does not have a prope
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/89865827252d7b8b.
Report an issue: GitHub.