{"record":{"id":"11d5528334af90c0","repo":"dotnet/efcore","slug":"the-parameter-parameter-cannot-be-added-to-the","errorCode":null,"errorMessage":"The parameter '{parameter}' cannot be added to the stored procedure '{sproc}' because another parameter with this name already exists.","messagePattern":"The parameter '(.+?)' cannot be added to the stored procedure '(.+?)' because another parameter with this name already exists\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":782,"sourceCode":"                                            property.GetAfterSaveBehavior()));\n                                }\n\n                                break;\n\n                            case StoreObjectType.DeleteStoredProcedure:\n                                break;\n\n                            default:\n                                Check.DebugFail(\"Unexpected stored procedure type: \" + storeObjectIdentifier.StoreObjectType);\n                                break;\n                        }\n                    }\n                }\n            }\n\n            if (!parameterNames.Add(parameter.Name))\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.StoredProcedureDuplicateParameterName(\n                        parameter.Name, storeObjectIdentifier.DisplayName()));\n            }\n\n            if (parameter.PropertyName == null)\n            {\n                continue;\n            }\n\n            switch (storeObjectIdentifier.StoreObjectType)\n            {\n                case StoreObjectType.InsertStoredProcedure:\n                case StoreObjectType.UpdateStoredProcedure:\n                    if (parameter.Direction != ParameterDirection.Input\n                        && !storeGeneratedProperties.Remove(property!.Name))\n                    {\n                        if (sproc.Parameters.Any(p => p.PropertyName == property.Name\n                                && p.ForOriginalValue != parameter.ForOriginalValue","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L764-L800","documentation":"Thrown when ValidateStoredProcedure iterates the parameters of a mapped sproc and finds two parameters with the same Name within a single stored procedure mapping. The validator maintains a HashSet<string> parameterNames per sproc and rejects the duplicate; sproc parameters must be uniquely named because EF builds a positional/named argument list keyed by name.","triggerScenarios":"Two .HasParameter(...) / .HasOriginalValueParameter(...) / .HasResultColumn(...) calls produce the same parameter Name on the same InsertUsingStoredProcedure / UpdateUsingStoredProcedure / DeleteUsingStoredProcedure. Common when HasParameter(p => p.Id) is combined with HasOriginalValueParameter(p => p.Id) without setting distinct names, or when a row-count parameter collides with a property parameter name.","commonSituations":"Copy-pasting parameter config across insert/update/delete sproc builders; mapping both current value and original value of the same property without specifying separate parameter names; an automatically generated concurrency-token parameter colliding with an explicit one.","solutions":["Inspect the sproc mapping and find both calls producing the same parameter Name; give them distinct names via the parameter-name overload: .HasParameter(\"foo_current\", p => p.Foo) and .HasParameter(\"foo_original\", p => p.Foo).","If one of the duplicates is the row-count/output value, configure it as a rows-affected parameter/result column rather than a regular parameter.","Remove the redundant HasParameter call entirely if both were intended to map the same property value."],"exampleFix":"// before\nentityType.UpdateUsingStoredProcedure(\"UpdateOrder\",\n    sp =>\n    {\n        sp.HasParameter(o => o.RowVersion); // produces \"RowVersion\"\n        sp.HasOriginalValueParameter(o => o.RowVersion); // also \"RowVersion\" -> duplicate\n    });\n\n// after\nentityType.UpdateUsingStoredProcedure(\"UpdateOrder\",\n    sp =>\n    {\n        sp.HasParameter(\"RowVersion_Current\", o => o.RowVersion);\n        sp.HasOriginalValueParameter(\"RowVersion_Original\", o => o.RowVersion);\n    });","handlingStrategy":"validation","validationCode":"// Assert unique parameter names per sproc mapping.\nforeach (var et in model.GetEntityTypes())\n{\n    foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure(), et.GetDeleteStoredProcedure() })\n    {\n        if (sproc == null) continue;\n        var names = sproc.Parameters.Select(p => p.Name).ToList();\n        var dupes = names.GroupBy(n => n).Where(g => g.Count() > 1).Select(g => g.Key);\n        foreach (var d in dupes)\n            Console.WriteLine($\"Duplicate parameter '{d}' on {sproc.Name}\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When mapping both current and original values of one property, always pass an explicit parameter name.","Use a small fluent helper to register sproc parameters from a single list, deduplicating by name.","Run a startup check that calls Database.GetService<IModelValidator>().Validate(model) in tests."],"tags":["ef-core","stored-procedures","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}