dotnet/efcore · error · ArgumentException

IsDescending and AllDescending cannot both be specified on t

Error message

IsDescending and AllDescending cannot both be specified on the [Index] attribute.

What it means

Thrown by the IndexAttribute.IsDescending setter when AllDescending has already been set to true. These two properties are mutually exclusive ways to express sort order, so EF Core forbids specifying both to avoid ambiguity. It fires at model-build time as soon as the conflicting assignment happens.

Source

Thrown at src/EFCore.Abstractions/IndexAttribute.cs:75

    /// <summary>
    ///     A set of values indicating whether each corresponding index column has descending sort order.
    /// </summary>
    public bool[]? IsDescending
    {
        get;
        set
        {
            if (value is not null)
            {
                if (value.Length != PropertyNames.Count)
                {
                    throw new ArgumentException(
                        AbstractionsStrings.InvalidNumberOfIndexSortOrderValues(value.Length, PropertyNames.Count), nameof(IsDescending));
                }

                if (AllDescending)
                {
                    throw new ArgumentException(AbstractionsStrings.CannotSpecifyBothIsDescendingAndAllDescending);
                }
            }

            field = value;
        }
    }

    /// <summary>
    ///     Whether all index columns have descending sort order.
    /// </summary>
    public bool AllDescending
    {
        get;
        set
        {
            if (IsDescending is not null)
            {
                throw new ArgumentException(AbstractionsStrings.CannotSpecifyBothIsDescendingAndAllDescending);

View on GitHub (pinned to dbf9771522)

Solutions

  1. Pick one mechanism: use IsDescending (per-column) OR AllDescending (uniform), never both.
  2. If you previously set AllDescending and now want per-column control, do not reuse the same attribute instance, or reset state so only IsDescending is set.
  3. Audit your IndexAttribute configuration to ensure the two properties are never assigned together.

Example fix

// before
var idx = new IndexAttribute("A", "B");
idx.AllDescending = true;
idx.IsDescending = new[] { true, false }; // throws

// after
var idx = new IndexAttribute("A", "B");
idx.IsDescending = new[] { true, false }; // pick one mechanism
Defensive patterns

Strategy: validation

Validate before calling

// Ensure mutual exclusion before assigning
if (value is not null && indexAttr.AllDescending)
{
    throw new InvalidOperationException("IsDescending conflicts with AllDescending already set.");
}
indexAttr.IsDescending = value;

Type guard

static bool CanSetIsDescending(IndexAttribute attr)
    => !attr.AllDescending;

Prevention

When it happens

Trigger: Assigning AllDescending = true first, then later assigning IsDescending = ... on the same IndexAttribute instance. The setter checks the already-set AllDescending and throws.

Common situations: Copy-pasting configuration between indexes where one used AllDescending and another used IsDescending. Incrementally building up an index attribute in code and accidentally setting both flags. Refactoring from a global descending flag to per-column flags without clearing the old flag.

Related errors


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