dotnet/efcore · error · InvalidOperationException
Original value parameter '{parameter}' is not allowed on ins
Error message
Original value parameter '{parameter}' is not allowed on insert stored procedure '{sproc}'. Use HasParameter() instead. What it means
Thrown when an original-value parameter (HasOriginalValueParameter) is configured on an Insert stored procedure. Inserts only use current values; original values have no meaning before a row exists. The validator rejects ForOriginalValue==true parameters on insert sprocs and suggests HasParameter instead.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:716
var originalValueProperties = new Dictionary<string, IProperty>(properties);
var parameterNames = new HashSet<string>();
foreach (var parameter in sproc.Parameters)
{
IProperty? property = null;
if (parameter.PropertyName != null)
{
if (parameter.ForOriginalValue == true)
{
if (!originalValueProperties.TryGetAndRemove(parameter.PropertyName, out property))
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureParameterNotFound(
parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));
}
if (storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureOriginalValueParameterOnInsert(
parameter.Name, storeObjectIdentifier.DisplayName()));
}
}
else
{
if (!properties.TryGetAndRemove(parameter.PropertyName, out property))
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureParameterNotFound(
parameter.PropertyName, entityType.DisplayName(), storeObjectIdentifier.DisplayName()));
}
if (storeObjectIdentifier.StoreObjectType == StoreObjectType.DeleteStoredProcedure)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureCurrentValueParameterOnDelete(
parameter.Name, storeObjectIdentifier.DisplayName()));View on GitHub (pinned to dbf9771522)
Solutions
- Replace HasOriginalValueParameter with HasParameter on the insert sproc.
- Remove the original-value parameter entirely if it is not needed for insert.
Example fix
// before
.InsertStoredProcedure("sp_InsertBlog", sp =>
{
sp.HasOriginalValueParameter("CreatedAt");
});
// after
.InsertStoredProcedure("sp_InsertBlog", sp =>
{
sp.HasParameter("CreatedAt");
}); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
var ins = et.GetInsertStoredProcedure();
if (ins != null && ins.Parameters.Any(p => p.ForOriginalValue == true))
throw new InvalidOperationException($"{et.DisplayName()} insert sproc has original-value params");
} Try / catch
try { _ = ctx.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("not allowed on insert stored procedure")) { /* replace HasOriginalValueParameter with HasParameter */ } Prevention
- On insert sprocs use HasParameter only; reserve HasOriginalValueParameter for update/delete.
When it happens
Trigger: .InsertStoredProcedure().HasOriginalValueParameter("RowVersion"); mixing concurrency-token-style original-value params onto an insert sproc.
Common situations: Copy-pasting update/delete sproc config (which may use original values) onto an insert sproc.
Related errors
- No property named '{property}' found on the entity type '{en
- Input parameter '{parameter}' of insert stored procedure '{s
- Current value parameter '{parameter}' is not allowed on dele
- Input parameter '{parameter}' of update stored procedure '{s
- The parameter '{parameter}' cannot be added to the stored pr
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/f7f626b81999545b.
Report an issue: GitHub.