dotnet/efcore · error · InvalidOperationException

'{facet}' cannot be configured for the parameter '{parameter

Error message

'{facet}' cannot be configured for the parameter '{parameter}' of the stored procedure '{sproc}'.

What it means

Thrown by StoredProcedureParameter.SetDirection when attempting to configure the Direction of a rows-affected parameter. Rows-affected parameters are always ParameterDirection.Output (set in the constructor at StoredProcedureParameter.cs:45), so EF forbids changing their direction — the error message lists the facet ('Direction') that cannot be configured.

Source

Thrown at src/EFCore.Relational/Metadata/Internal/StoredProcedureParameter.cs:207

    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual ParameterDirection Direction
    {
        get => _direction ?? ParameterDirection.Input;
        set => SetDirection(value, ConfigurationSource.Explicit);
    }

    /// <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 ParameterDirection SetDirection(ParameterDirection direction, ConfigurationSource configurationSource)
    {
        if (ForRowsAffected)
        {
            throw new InvalidOperationException(
                RelationalStrings.StoredProcedureParameterInvalidConfiguration(
                    nameof(Direction), Name, ((IReadOnlyStoredProcedure)StoredProcedure).GetStoreIdentifier()?.DisplayName()));
        }

        if (!IsValid(direction))
        {
            throw new InvalidOperationException(
                RelationalStrings.StoredProcedureParameterInvalidDirection(
                    direction, Name, ((IReadOnlyStoredProcedure)StoredProcedure).GetStoreIdentifier()?.DisplayName()));
        }

        _direction = direction;

        _directionConfigurationSource = configurationSource.Max(_directionConfigurationSource);

        return direction;
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Do not set Direction on a rows-affected parameter — it is implicitly Output.
  2. In generic loops, skip parameters where parameter.ForRowsAffected is true before configuring Direction.
  3. If you need an Input parameter, add it via AddParameter(propertyName) instead of AddRowsAffectedParameter().

Example fix

// before
var p = s.AddRowsAffectedParameter();
p.Direction = ParameterDirection.InputOutput; // throws

// after
var p = s.AddRowsAffectedParameter();
// leave Direction alone; it is Output by default
Defensive patterns

Strategy: type-guard

Validate before calling

static void SetDirectionSafe(StoredProcedureParameter p, ParameterDirection direction)
{
    if (p.ForRowsAffected)
    {
        throw new InvalidOperationException("Cannot set Direction on a rows-affected parameter.");
    }
    p.Direction = direction;
}

Type guard

static bool CanConfigureDirection(StoredProcedureParameter p) => !p.ForRowsAffected;

Prevention

When it happens

Trigger: StoredProcedureParameter.cs:205-210: ForRowsAffected is true when SetDirection is called. Produced by obtaining the parameter from AddRowsAffectedParameter() and then assigning .Direction or calling .HasDirection(...).

Common situations: Treating the rows-affected parameter like a normal parameter and setting Input/InputOutput; generic parameter-configuration loops that set Direction on every parameter including the rows-affected one.

Related errors


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