dotnet/efcore · error · InvalidOperationException

Unsupported direction

Error message

Unsupported direction '{direction}' was specified for the parameter '{parameter}' of the stored procedure '{sproc}'.

What it means

SetDirection rejects ParameterDirection values that are incompatible with the parameter's role. IsValid forbids ReturnValue for any parameter and forbids Output when the parameter carries the original (pre-update) value, since an original-value column must be supplied as input.

Solutions

  1. Call parameter.IsValid(direction) before SetDirection and skip/adjust on false.
  2. Use Output only on parameters that are not original-value parameters; never use ReturnValue on a stored-procedure parameter.
  3. For rows affected via return value, use RowsAffectedReturned() on the procedure, not a ReturnValue parameter.
  4. Re-check the parameter kind (ForOriginalValue) before assigning direction.

Example fix

// before
sp.OriginalValueParameter("RowVersion")
  .HasDirection(ParameterDirection.Output); // throws

// after
sp.OriginalValueParameter("RowVersion")
  .HasDirection(ParameterDirection.Input);
Defensive patterns

Strategy: validation

Validate before calling

if (parameter.IsValid(direction))
{
    parameter.HasDirection(direction);
}

Type guard

static bool IsDirectionAllowed(StoredProcedureParameter p, ParameterDirection d)
    => p.IsValid(d);

Prevention

When it happens

Trigger: Calling .HasDirection(ParameterDirection.ReturnValue) on any parameter, or .HasDirection(ParameterDirection.Output) on a parameter created with originalValue: true (OriginalValueParameter()).

Common situations: Assuming every parameter can be Output; mapping audit columns as output when the procedure reads the original row version; scaffolding code that blanket-applies Output to all non-input parameters.

Related errors


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

Appendix: source

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

    /// <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;
    }

    /// <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 bool IsValid(ParameterDirection direction)

View on GitHub (pinned to 3a2006ef56)