dotnet/efcore · error · InvalidOperationException
The property '{entityType}.{property}' is mapped to an outpu
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 during model validation when an Insert/Update stored procedure maps a property to an output (or input-output) parameter, but that property is not configured as store-generated (ValueGenerated). EF uses output parameters to read back values the database generates (e.g. identity/computed columns), so an output parameter on a non-generated property is meaningless and almost always a configuration mistake. The validator at line 796-811 checks `parameter.Direction != ParameterDirection.Input` and requires the property be in the storeGenerated set.
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 dbf9771522)
Solutions
- Mark the property as store-generated, e.g. propertyBuilder.ValueGeneratedOnAdd() or .HasComputedColumnSql("...").
- If the value is not database-generated, change the parameter direction to input-only by using .Parameter(...) instead of .OutputParameter(...)/.InputOutputParameter(...).
- Remove the parameter mapping entirely if the sproc does not actually return that value.
Example fix
// before
modelBuilder.Entity<Order>()
.InsertStoredProcedure(o => o
.Parameter(p => p.Status, "status")
.OutputParameter(p => p.Status, "status_out")); // Status is not store-generated
// after - make it input only since Status is set by the client
modelBuilder.Entity<Order>()
.InsertStoredProcedure(o => o
.Parameter(p => p.Status, "status"));
// OR mark it generated:
// modelBuilder.Entity<Order>().Property(p => p.Status).ValueGeneratedOnAdd(); Defensive patterns
Strategy: validation
Validate before calling
// Before finalizing the model, ensure each output/inputOutput parameter
// on an Insert/Update sproc targets a store-generated property.
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
foreach (var sproc in et.GetStoredProcedures())
{
if (sproc.StoreObjectType is StoreObjectType.InsertStoredProcedure
or StoreObjectType.UpdateStoredProcedure)
{
var generated = et.GetProperties()
.Where(p => p.ValueGenerated != ValueGenerated.Never)
.Select(p => p.Name).ToHashSet();
foreach (var param in sproc.Parameters)
{
if (param.Direction != ParameterDirection.Input
&& param.PropertyName is string name
&& !generated.Contains(name))
{
throw new InvalidOperationException(
$"Output param '{param.Name}' on {et.Name} maps non-generated property '{name}'.");
}
}
}
}
} Prevention
- Only map output/inputOutput parameters for properties explicitly marked ValueGeneratedOnAdd/OnUpdate or HasComputedColumnSql.
- Review the database sproc signature: OUT params should correspond 1:1 to generated columns.
- Run a model-validation unit test (model.FinalizeModel()) in CI to catch this before runtime.
When it happens
Trigger: Calling `.InsertStoredProcedure(...)` or `.UpdateStoredProcedure(...)` on an entity and using `.OutputParameter()` / `.InputOutputParameter()` for a property that has no `.ValueGeneratedOnAdd()` / `.ValueGeneratedOnUpdate()` / `.HasComputedColumnSql()` configuration. The check fires for InsertStoredProcedure and UpdateStoredProcedure store object types only.
Common situations: Developer maps every column to an output parameter by habit; copy-pasting a parameter list from a SQL sproc signature into EF config without marking computed/identity columns; switching a property from database-generated to client-set but forgetting to drop the output parameter mapping.
Related errors
- The entity type '{entityType}' was configured to use some st
- The entity type '{entityType}' was configured to use '{sproc
- The keyless entity type '{entityType}' was configured to use
- The property '{entityType}.{property}' is mapped to a result
- The entity type '{entityType}' is mapped to the stored proce
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/75fcef21dd6ddf4a.
Report an issue: GitHub.