dotnet/efcore · error · InvalidOperationException
The property ' . ' is mapped to an output parameter of the…
Error message
The property '{entityType}.{property}' is mapped to an output parameter of the stored procedure '{sproc}', but it is not configured as store-generated. Either configure it as store-generated or don't configure the parameter as output. What it means
Thrown when an insert/update sproc parameter is configured as Output (or InputOutput / ReturnValue) and bound to a property that is NOT store-generated. The validator only allows non-input parameters for properties in the storeGeneratedProperties set; failing to remove the property from that set means the database will not supply a value, so an output parameter is meaningless and the model is rejected.
Solutions
- Configure the property as store-generated: builder.Property(p => p.Foo).ValueGeneratedOnAdd() / .HasDefaultValueSql(...) / .HasComputedColumnSql(...) so it belongs in storeGeneratedProperties.
- If the property is not store-generated, change the parameter to Input: use HasParameter(p => p.Foo) instead of HasOutputParameter(p => p.Foo).
- Remove the parameter mapping entirely if the sproc does not actually populate it.
Example fix
// before
entityType.InsertUsingStoredProcedure("InsertOrder",
sp => sp.HasOutputParameter(o => o.CustomerName)); // not store-generated
// after
entityType.InsertUsingStoredProcedure("InsertOrder",
sp => sp.HasParameter(o => o.CustomerName));
// or, if the DB really populates it:
// builder.Property(o => o.CustomerName).HasDefaultValueSql("..."); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in model.GetEntityTypes())
{
foreach (var sproc in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure() })
{
if (sproc == null) continue;
foreach (var p in sproc.Parameters.Where(p => p.Direction != System.Data.ParameterDirection.Input))
{
if (p.PropertyName is string name)
{
var prop = et.FindProperty(name);
if (prop?.ValueGenerated == Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.Never
&& prop?.GetDefaultValue() == null
&& prop?.GetDefaultValueSql() == null
&& prop?.GetComputedColumnSql() == null)
{
Console.WriteLine($"{et.Name}.{name} is output on {sproc.Name} but not store-generated.");
}
}
}
}
} Prevention
- Pair every HasOutputParameter call with a ValueGenerated/HasDefaultValueSql/HasComputedColumnSql config on the same property.
- Run EF Core's model validator explicitly in unit tests.
- Document for each output parameter which DDL feature backs its generated value.
When it happens
Trigger: .HasOutputParameter(p => p.NonGeneratedColumn) on an Insert/Update sproc where NonGeneratedColumn has no ValueGenerated configuration and no database default/computed setting. The Direction is set to Output or InputOutput on a property EF considers user-supplied.
Common situations: Marking a regular property as an output parameter expecting the sproc to echo it back; confusing HasOutputParameter with HasParameter; flipping a column from database-generated to client-generated without updating the sproc mapping.
Related errors
- The entity type ' ' is mapped to the stored procedure ' '…
- The property ' . ' is mapped to an output parameter of the…
- The property ' . ' is mapped to a result column of the…
- A rows affected parameter, result column or return value…
- Both ' ' and ' ' are explicitly mapped to the stored…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/75fcef21dd6ddf4a.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:808
}
switch (storeObjectIdentifier.StoreObjectType)
{
case StoreObjectType.InsertStoredProcedure:
case StoreObjectType.UpdateStoredProcedure:
if (parameter.Direction != ParameterDirection.Input
&& !storeGeneratedProperties.Remove(property!.Name))
{
if (sproc.Parameters.Any(p => p.PropertyName == property.Name
&& p.ForOriginalValue != parameter.ForOriginalValue
&& p.Direction != ParameterDirection.Input))
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureOutputParameterConflict(
entityType.DisplayName(), parameter.PropertyName, storeObjectIdentifier.DisplayName()));
}
throw new InvalidOperationException(
RelationalStrings.StoredProcedureOutputParameterNotGenerated(
entityType.DisplayName(), parameter.PropertyName, storeObjectIdentifier.DisplayName()));
}
break;
case StoreObjectType.DeleteStoredProcedure:
if (!property!.IsPrimaryKey()
&& !property.IsConcurrencyToken)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureDeleteNonKeyProperty(
entityType.DisplayName(), parameter.PropertyName, storeObjectIdentifier.DisplayName()));
}
break;
default:
Check.DebugFail("Unexpected stored procedure type: " + storeObjectIdentifier.StoreObjectType);
break;View on GitHub (pinned to 3a2006ef56)