{"record":{"id":"f7f626b81999545b","repo":"dotnet/efcore","slug":"original-value-parameter-parameter-is-not-allo","errorCode":null,"errorMessage":"Original value parameter '{parameter}' is not allowed on insert stored procedure '{sproc}'. Use HasParameter() instead.","messagePattern":"Original value parameter '(.+?)' is not allowed on insert stored procedure '(.+?)'\\. Use HasParameter\\(\\) instead\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":716,"sourceCode":"        var originalValueProperties = new Dictionary<string, IProperty>(properties);\n        var parameterNames = new HashSet<string>();\n        foreach (var parameter in sproc.Parameters)\n        {\n            IProperty? property = null;\n            if (parameter.PropertyName != null)\n            {\n                if (parameter.ForOriginalValue == true)\n                {\n                    if (!originalValueProperties.TryGetAndRemove(parameter.PropertyName, out property))\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureParameterNotFound(\n                                parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));\n                    }\n\n                    if (storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure)\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureOriginalValueParameterOnInsert(\n                                parameter.Name, storeObjectIdentifier.DisplayName()));\n                    }\n                }\n                else\n                {\n                    if (!properties.TryGetAndRemove(parameter.PropertyName, out property))\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureParameterNotFound(\n                                parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));\n                    }\n\n                    if (storeObjectIdentifier.StoreObjectType == StoreObjectType.DeleteStoredProcedure)\n                    {\n                        throw new InvalidOperationException(\n                            RelationalStrings.StoredProcedureCurrentValueParameterOnDelete(\n                                parameter.Name, storeObjectIdentifier.DisplayName()));","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L698-L734","documentation":"Thrown when a parameter on an Insert stored procedure is configured as an original-value parameter (parameter.ForOriginalValue == true and StoreObjectType == InsertStoredProcedure) at RelationalModelValidator.cs:714-719. Insert operations never read original (pre-save) values — they only write new ones — so HasOriginalValueParameter is meaningless on insert and rejected.","triggerScenarios":"Calling .HasOriginalValueParameter(x => x.Foo) inside an .InsertUsingStoredProcedure(... ) configuration block. Usually a copy-paste from an update or delete sproc.","commonSituations":"Refactoring a shared sproc configuration helper to apply to insert/update/delete uniformly; copy-pasting an update sproc template to an insert sproc; misreading the API surface.","solutions":["Replace .HasOriginalValueParameter(...) with .HasParameter(...) (current-value/input) in the insert configuration.","If you need a server-generated value on insert, use .HasResultColumn(...) on a store-generated property instead.","Keep original-value parameters only on Update and Delete sproc configurations."],"exampleFix":"// before\nmodelBuilder.Entity<Customer>()\n    .InsertUsingStoredProcedure(\"dbo.CustomerInsert\", sp =>\n    {\n        sp.HasParameter(c => c.Name);\n        sp.HasOriginalValueParameter(c => c.Id); // throws on insert\n    });\n\n// after\nmodelBuilder.Entity<Customer>()\n    .InsertUsingStoredProcedure(\"dbo.CustomerInsert\", sp =>\n    {\n        sp.HasParameter(c => c.Name);\n        sp.HasResultColumn(c => c.Id); // identity, read back as result\n    });","handlingStrategy":"validation","validationCode":"foreach (var et in modelBuilder.Model.GetEntityTypes())\n{\n    var insert = et.GetInsertStoredProcedure();\n    if (insert is null) continue;\n    if (insert.Parameters.Any(p => p.ForOriginalValue == true))\n        throw new InvalidOperationException($\"Insert sproc '{insert.GetStoreIdentifier().DisplayName}' on '{et.Name}' must not have original-value parameters.\");\n}","typeGuard":null,"tryCatchPattern":"try { _ = ctx.Model; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not allowed on insert stored procedure\"))\n{\n    logger.LogError(\"Use HasParameter, not HasOriginalValueParameter, on insert. {Msg}\", ex.Message);\n    throw;\n}","preventionTips":["Reserve HasOriginalValueParameter for Update/Delete sproc configs only.","Write a small Roslyn analyzer or unit test asserting insert sproc parameters are all current-value.","Don't share a single lambda-based builder across insert/update/delete uniformly."],"tags":["efcore","relational","stored-procedure","parameter","original-value","insert","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}