dotnet/efcore · error · InvalidOperationException

The parameter for the property

Error message

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

What it means

Thrown when AddParameter(propertyName) is called for a property that already has a current-value parameter on the stored procedure mapping. A property may have at most one current-value parameter.

Solutions

  1. Check whether the parameter already exists (StoredProcedure.FindParameter(propertyName)) before adding.
  2. Remove the duplicate HasParameter call.
  3. If you need original-value semantics, use AddOriginalValueParameter instead of a second AddParameter.
  4. Build the mapping once, declaratively, to avoid programmatic double-add.

Example fix

// before
insertSproc.HasParameter(p => p.Name);
insertSproc.HasParameter(p => p.Name); // throws

// after: declare each parameter once
insertSproc.HasParameter(p => p.Name);
Defensive patterns

Strategy: validation

Validate before calling

// Before adding a parameter, check existence.
if (sproc.FindParameter(propertyName) is null)
    sproc.HasParameter(propertyName);
else
    Console.WriteLine($"Parameter for '{propertyName}' already exists; skipping.");

Prevention

When it happens

Trigger: StoredProcedure.AddParameter(propertyName) when _currentValueParameters.ContainsKey(propertyName). Triggered by calling HasParameter(p => p.X) twice, or mixing fluent calls that both resolve to a current-value parameter for the same property.

Common situations: Copy/paste of HasParameter calls; combining attribute-based stored procedure mapping with fluent configuration; building parameters programmatically without checking existence; refactoring mappings that double-add the same property.

Related errors


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

Appendix: source

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

    ///     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? FindParameter(string propertyName)
        => _currentValueParameters.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 AddParameter(string propertyName)
    {
        if (_currentValueParameters.ContainsKey(propertyName))
        {
            throw new InvalidOperationException(
                RelationalStrings.StoredProcedureDuplicateParameter(
                    propertyName, ((IReadOnlyStoredProcedure)this).GetStoreIdentifier()?.DisplayName()));
        }

        var parameter = new StoredProcedureParameter(this, rowsAffected: false, propertyName, originalValue: false);
        _parameters.Add(parameter);
        _currentValueParameters.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? FindOriginalValueParameter(string propertyName)

View on GitHub (pinned to 3a2006ef56)