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
- Pick one mechanism: use IsDescending (per-column) OR AllDescending (uniform), never both.
- 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.
- 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
- Treat IsDescending and AllDescending as mutually exclusive; never assign both to one attribute.
- Reset/avoid reusing attribute instances when switching sort-order strategy.
- Add a unit test asserting only one of the two is ever set per index.
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
- Invalid number of index sort order values: {numValues} value
- The number argument cannot be a negative number.
- The value '{value}' provided for argument '{argumentName}' m
- Cosmos-specific methods can only be used when the context is
- A synchronous store management operation was performed and n
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/583207320a60c2a4.
Report an issue: GitHub.