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 also mapped to an output original value output parameter. A store-generated property can only be mapped to one output parameter.

What it means

Thrown when a store-generated property is mapped to two output parameters that differ by original-value flag (one current-value output and one original-value output). A single store-generated property can only map to one output parameter. The validator detects another output parameter for the same property with a different ForOriginalValue value.

Source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:803

            }

            if (parameter.PropertyName == null)
            {
                continue;
            }

            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()));
                    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Remove one of the output parameter mappings so the property maps to exactly one output parameter.
  2. Keep the current-value output parameter and drop the original-value one (or vice-versa).

Example fix

// before
sp.HasOutputParameter("Version");
sp.HasOriginalValueParameter("Version"); // output + original output

// after
sp.HasOutputParameter("Version");
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    foreach (var s in new[] { et.GetInsertStoredProcedure(), et.GetUpdateStoredProcedure() }.Where(s => s != null))
    {
        var outputs = s.Parameters.Where(p => p.PropertyName != null && p.Direction != System.Data.ParameterDirection.Input);
        var dup = outputs.GroupBy(p => p.PropertyName).Where(g => g.Select(x => x.ForOriginalValue).Distinct().Count() > 1);
        if (dup.Any()) throw new InvalidOperationException($"Property {dup.First().Key} mapped to multiple output params on {s.GetStoreIdentifier().Name}");
    }
}

Try / catch

try { _ = ctx.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("mapped to an output parameter") && ex.Message.Contains("output original value output parameter")) { /* remove one of the conflicting output parameter mappings */ }

Prevention

When it happens

Trigger: Both .HasOutputParameter("Version") and .HasOriginalValueParameter("Version") (with output direction) on the same store-generated property; double-binding a computed column as both current and original output.

Common situations: Trying to capture both the new and old generated value of one property; over-mapping a single store-generated column.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/180d39cdf45df585. Report an issue: GitHub.