dotnet/efcore · error · InvalidOperationException

The original value parameter for the property

Error message

The original value parameter for the property '{property}' cannot be added to the stored procedure '{sproc}' because another original value parameter for this property already exists.

What it means

Thrown when AddOriginalValueParameter(propertyName) is called for a property that already has an original-value parameter on the stored procedure mapping. A property may have at most one original-value parameter (used for optimistic concurrency updates).

Solutions

  1. Check StoredProcedure.FindOriginalValueParameter(propertyName) before adding.
  2. Remove the duplicate HasOriginalValueParameter call.
  3. Build the update mapping once, declaratively.
  4. Distinguish current-value vs original-value parameters if both are intended (they are separate channels and do not conflict with each other).

Example fix

// before
updateSproc.HasOriginalValueParameter(p => p.RowVersion);
updateSproc.HasOriginalValueParameter(p => p.RowVersion); // throws

// after: declare once
updateSproc.HasOriginalValueParameter(p => p.RowVersion);
Defensive patterns

Strategy: validation

Validate before calling

// Before adding an original-value parameter, check existence.
if (sproc.FindOriginalValueParameter(propertyName) is null)
    sproc.HasOriginalValueParameter(propertyName);
else
    Console.WriteLine($"Original-value parameter for '{propertyName}' already exists; skipping.");

Prevention

When it happens

Trigger: StoredProcedure.AddOriginalValueParameter(propertyName) when _originalValueParameters.ContainsKey(propertyName). Triggered by calling HasOriginalValueParameter(p => p.X) twice, or repeating an update mapping configuration that re-adds the same original-value parameter.

Common situations: Update stored procedure mappings built programmatically with duplicate calls; combining attribute and fluent configuration that both add the same original-value parameter; copy/paste errors.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/64881a9e28114ed7. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs:544

    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual StoredProcedureParameter? FindOriginalValueParameter(string propertyName)
        => _originalValueParameters.GetValueOrDefault(propertyName);

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual StoredProcedureParameter AddOriginalValueParameter(string propertyName)
    {
        if (_originalValueParameters.ContainsKey(propertyName))
        {
            throw new InvalidOperationException(
                RelationalStrings.StoredProcedureDuplicateOriginalValueParameter(
                    propertyName, ((IReadOnlyStoredProcedure)this).GetStoreIdentifier()?.DisplayName()));
        }

        var parameter = new StoredProcedureParameter(this, rowsAffected: false, propertyName, originalValue: true);
        _parameters.Add(parameter);
        _originalValueParameters.Add(propertyName, parameter);

        return parameter;
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual StoredProcedureParameter? FindRowsAffectedParameter()

View on GitHub (pinned to 3a2006ef56)