dotnet/aspnetcore · error · InvalidOperationException
The type '{targetType.FullName}' declares more than one para
Error message
The type '{targetType.FullName}' declares more than one parameter matching the name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique. What it means
Blazor component parameter names are matched case-insensitively. When the framework builds the parameter cache for a component type, it detects that two properties decorated with [Parameter] or [CascadingParameter] resolve to the same lowercased name and throws InvalidOperationException. This is a design-time correctness check that prevents ambiguous parameter binding at runtime.
Source
Thrown at src/Components/Components/src/Reflection/ComponentProperties.cs:333
continue;
}
var propertyName = propertyInfo.Name;
if (parameterAttribute != null && (propertyInfo.SetMethod == null || !propertyInfo.SetMethod.IsPublic))
{
throw new InvalidOperationException(
$"The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public.");
}
var propertySetter = new PropertySetter(targetType, propertyInfo)
{
AcceptsDirectParameters = acceptsDirectParameters,
AcceptsCascadingParameters = acceptsCascadingParameters,
};
if (_underlyingWriters.ContainsKey(propertyName))
{
throw new InvalidOperationException(
$"The type '{targetType.FullName}' declares more than one parameter matching the " +
$"name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique.");
}
_underlyingWriters.Add(propertyName, propertySetter);
if (parameterAttribute != null && parameterAttribute.CaptureUnmatchedValues)
{
// This is an "Extra" parameter.
//
// There should only be one of these.
if (CaptureUnmatchedValuesWriter != null)
{
ThrowForMultipleCaptureUnmatchedValuesParameters(targetType);
}
// It must be able to hold a Dictionary<string, object> since that's what we create.
if (!propertyInfo.PropertyType.IsAssignableFrom(typeof(Dictionary<string, object>)))View on GitHub (pinned to 294cab2f9b)
Solutions
- Inspect the component type named in the error and search for [Parameter] or [CascadingParameter] properties that differ only by case.
- Check all base classes of the component type for parameters whose names collide case-insensitively with the derived class's parameters.
- Rename one of the colliding properties to a distinct name and update all usages in markup (.razor files) and C# code.
- If using [CascadingParameter] alongside [Parameter] for the same property, combine them on a single property declaration.
Example fix
// before
[Parameter] public string? Title { get; set; }
[Parameter] public string? title { get; set; } // collides
// after
[Parameter] public string? Title { get; set; }
[Parameter] public string? Subtitle { get; set; } Defensive patterns
Strategy: validation
Validate before calling
// Validate before component registration
static void ValidateNoDuplicateParameterNames(Type componentType)
{
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var prop in componentType.GetProperties(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
var hasParam = prop.GetCustomAttribute<ParameterAttribute>() != null
|| prop.GetCustomAttribute<CascadingParameterAttribute>() != null;
if (!hasParam) continue;
if (!seen.Add(prop.Name))
throw new InvalidOperationException(
$"Duplicate parameter '{prop.Name}' on {componentType.FullName}");
}
}
// Call: ValidateNoDuplicateParameterNames(typeof(MyComponent)); Type guard
// Compile-time guard via generic constraint is not possible for attribute-based params. // Use a Roslyn analyzer or source generator to detect duplicate [Parameter] names at build time.
Prevention
- Use a Roslyn analyzer to flag duplicate case-insensitive [Parameter] names at compile time.
- Establish a naming convention for parameters (PascalCase) and avoid partial-case variants.
- During code reviews, check that renamed parameters have no leftover casing-different duplicates.
- Run a startup validation pass over all registered component types in test fixtures.
When it happens
Trigger: A component declares two parameter properties whose names differ only by case (e.g., [Parameter] public string? Title and [Parameter] public string? title). Also triggered when a derived component redeclares a [Parameter] that already exists on a base component with different casing, or when an explicitly implemented interface property collides with a declared parameter name.
Common situations: Copy-pasting a property and renaming with different casing; inheriting from a base component that already declares a similarly-named parameter; refactoring a property name and accidentally leaving the old casing behind; VB.NET interop where case-insensitivity is the norm but clashes with Blazor's own case-insensitive matching.
Related errors
- Invalid layout type: {layoutType.FullName} does not implemen
- Services cannot be accessed before the component is initiali
- Unable to set property '{parameterName}' on object of type '
- 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/dae09a1338998cbc.
Report an issue: GitHub.