{"record":{"id":"dae09a1338998cbc","repo":"dotnet/aspnetcore","slug":"the-type-targettype-fullname-declares-more-tha","errorCode":null,"errorMessage":"The type '{targetType.FullName}' declares more than one parameter matching the name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique.","messagePattern":"The type '(.+?)' declares more than one parameter matching the name '(.+?)'\\. Parameter names are case-insensitive and must be unique\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Reflection/ComponentProperties.cs","lineNumber":333,"sourceCode":"                    continue;\n                }\n\n                var propertyName = propertyInfo.Name;\n                if (parameterAttribute != null && (propertyInfo.SetMethod == null || !propertyInfo.SetMethod.IsPublic))\n                {\n                    throw new InvalidOperationException(\n                        $\"The type '{targetType.FullName}' declares a parameter matching the name '{propertyName}' that is not public. Parameters must be public.\");\n                }\n\n                var propertySetter = new PropertySetter(targetType, propertyInfo)\n                {\n                    AcceptsDirectParameters = acceptsDirectParameters,\n                    AcceptsCascadingParameters = acceptsCascadingParameters,\n                };\n\n                if (_underlyingWriters.ContainsKey(propertyName))\n                {\n                    throw new InvalidOperationException(\n                        $\"The type '{targetType.FullName}' declares more than one parameter matching the \" +\n                        $\"name '{propertyName.ToLowerInvariant()}'. Parameter names are case-insensitive and must be unique.\");\n                }\n\n                _underlyingWriters.Add(propertyName, propertySetter);\n\n                if (parameterAttribute != null && parameterAttribute.CaptureUnmatchedValues)\n                {\n                    // This is an \"Extra\" parameter.\n                    //\n                    // There should only be one of these.\n                    if (CaptureUnmatchedValuesWriter != null)\n                    {\n                        ThrowForMultipleCaptureUnmatchedValuesParameters(targetType);\n                    }\n\n                    // It must be able to hold a Dictionary<string, object> since that's what we create.\n                    if (!propertyInfo.PropertyType.IsAssignableFrom(typeof(Dictionary<string, object>)))","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Reflection/ComponentProperties.cs#L315-L351","documentation":"WritersForType builds its parameter-name cache case-insensitively (StringComparer.OrdinalIgnoreCase). When two properties both resolve to the same parameter name (e.g., 'Count' and 'count'), the second registration collides and throws. Blazor parameter names are case-insensitive on the consumer side, so duplicate names differing only by case are ambiguous and rejected at cache-construction time.","triggerScenarios":"Declaring two [Parameter] (or [CascadingParameter]) properties on the same component whose names differ only by case, e.g., 'Title' and 'title'. The collision is detected when _underlyingWriters already contains the lower-cased key. Inheritance can also cause it if base and derived declare same-named parameters.","commonSituations":"Refactoring that introduces a similarly-named parameter. Inherited components overriding or shadowing a base parameter with a differently-cased duplicate. Copy-paste errors. Casing inconsistencies between C# property name and a Razor attribute.","solutions":["Rename one of the colliding parameters so the names are unique case-insensitively.","If the collision comes from inheritance, remove the duplicate in the derived type or rename the base.","Establish a casing convention (PascalCase for parameters) across the component hierarchy."],"exampleFix":"// before\n[Parameter] public string? Title { get; set; }\n[Parameter] public string? title { get; set; } // throws\n\n// after\n[Parameter] public string? Title { get; set; }\n[Parameter] public string? Subtitle { get; set; }","handlingStrategy":"validation","validationCode":"// Detect case-insensitive parameter name collisions across the type hierarchy.\nvar seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\nforeach (var p in typeof(MyComponent).GetProperties(\n    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))\n{\n    bool isParam = p.GetCustomAttribute<ParameterAttribute>() != null\n        || p.GetCustomAttributes().OfType<CascadingParameterAttributeBase>().Any();\n    if (!isParam) continue;\n    if (!seen.Add(p.Name))\n        throw new InvalidOperationException($\"Duplicate parameter name '{p.Name}' (case-insensitive).\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use distinct, PascalCase parameter names throughout the hierarchy.","Add a unit test that detects case-insensitive duplicates per component type.","When inheriting, check the base type's parameters before adding new ones."],"tags":["blazor","parameters","reflection","naming"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}