dotnet/efcore · error · ArgumentException
{numSortOrderProperties} values were provided in CreateIndex
Error message
{numSortOrderProperties} values were provided in CreateIndexOperations.IsDescending, but the operation has {numColumns} columns. What it means
Thrown by the CreateIndexOperation.Columns setter when assigning a new columns array whose length does not match the already-set IsDescending array length. The two arrays must be element-aligned (one sort-order flag per column), so EF rejects any mismatch as an ArgumentException at assignment time.
Source
Thrown at src/EFCore.Relational/Migrations/Operations/CreateIndexOperation.cs:43
/// </summary>
public virtual string? Schema { get; set; }
/// <summary>
/// The table that contains the index.
/// </summary>
public virtual string Table { get; set; } = null!;
/// <summary>
/// The ordered list of column names for the column that make up the index.
/// </summary>
public virtual string[] Columns
{
get => _columns!;
set
{
if (_isDescending is not null && _isDescending.Length > 0 && value.Length != _isDescending.Length)
{
throw new ArgumentException(RelationalStrings.CreateIndexOperationWithInvalidSortOrder(_isDescending.Length, value.Length));
}
_columns = value;
}
}
/// <summary>
/// Indicates whether or not the index should enforce uniqueness.
/// </summary>
public virtual bool IsUnique { get; set; }
/// <summary>
/// A set of values indicating whether each corresponding index column has descending sort order.
/// </summary>
public virtual bool[]? IsDescending
{
get => _isDescending;
setView on GitHub (pinned to dbf9771522)
Solutions
- Ensure the Columns array and the IsDescending array have identical lengths when setting Columns after IsDescending.
- Set IsDescending to null before changing the column count, then assign the correctly-sized IsDescending array afterwards.
- Construct both arrays together from the same source (e.g. project from the index's columns) so they cannot drift.
Example fix
// before
var op = new CreateIndexOperation
{
Name = "IX",
Table = "T",
IsDescending = new[] { true, false }
};
op.Columns = new[] { "A" }; // length mismatch -> throws
// after
op.Columns = new[] { "A", "B" }; // matches IsDescending length Defensive patterns
Strategy: validation
Validate before calling
static CreateIndexOperation BuildIndex(string table, string[] cols, bool[]? desc)
{
if (desc is { Length: > 0 } && desc.Length != cols.Length)
throw new ArgumentException($"IsDescending length {desc.Length} != columns {cols.Length}");
return new CreateIndexOperation { Name = "IX_" + table, Table = table, Columns = cols, IsDescending = desc };
} Prevention
- Build Columns and IsDescending from the same source list so they cannot diverge.
- Set IsDescending to null when changing column count, then assign the matching array.
When it happens
Trigger: Setting operation.Columns after operation.IsDescending with arrays of different lengths; creating a CreateIndexOperation where IsDescending was assigned first and Columns is later set to a differently-sized array.
Common situations: Hand-building a CreateIndexOperation in code/migrations with mismatched array sizes; copying an index operation and editing only one of the two arrays; provider/annotation code that mutates Columns after IsDescending is populated.
Related errors
- A migration name must be specified.
- The migration name '{name}' is not valid. Migration names ca
- The name you have chosen for the migration, '{name}', is the
- The number of elements ({elementCount}) must match the numbe
- The value '{value}' provided for argument '{argumentName}' m
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/88b4504d9b94da7c.
Report an issue: GitHub.