dotnet/efcore · error · InvalidOperationException

Reversing the ordering is not supported when limit or offset

Error message

Reversing the ordering is not supported when limit or offset are already applied.

What it means

SelectExpression.ReverseOrderings throws InvalidOperationException when Reverse() is applied after a Limit (Take) or Offset (Skip) has already been set. Reversing an already-paged ordering cannot be expressed in Cosmos SQL without changing semantics, so the provider rejects it.

Source

Thrown at src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs:508

        if (_orderings.FirstOrDefault(o => o.Expression.Equals(orderingExpression.Expression)) == null)
        {
            _orderings.Add(orderingExpression);
        }
    }

    /// <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 void ReverseOrderings()
    {
        if (Limit != null
            || Offset != null)
        {
            throw new InvalidOperationException(CosmosStrings.ReverseAfterSkipTakeNotSupported);
        }

        var existingOrderings = _orderings.ToArray();

        _orderings.Clear();

        foreach (var existingOrdering in existingOrderings)
        {
            _orderings.Add(
                new OrderingExpression(
                    existingOrdering.Expression,
                    !existingOrdering.IsAscending));
        }
    }

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

View on GitHub (pinned to dbf9771522)

Solutions

  1. Apply Reverse before Skip/Take, or equivalently order descending from the start instead of reversing after paging.
  2. Switch the original OrderBy direction (OrderByDescending) and keep paging, avoiding Reverse entirely.
  3. Perform the reversal client-side after materializing the page.

Example fix

// before
var q = ctx.Logs.OrderBy(l => l.Time)
    .Skip(0).Take(10).Reverse();

// after (page the descending order directly)
var q = ctx.Logs.OrderByDescending(l => l.Time)
    .Skip(0).Take(10);
Defensive patterns

Strategy: validation

Validate before calling

// Guard against Reverse after paging by reordering the query construction.
static IQueryable<T> Paged<T, K>(IQueryable<T> q, Expression<Func<T,K>> key, int skip, int take, bool desc)
    => (desc ? q.OrderByDescending(key) : q.OrderBy(key)).Skip(skip).Take(take);

Try / catch

try { var q = query.Reverse().ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Reversing the ordering"))
{ /* reverse before Skip/Take, or order descending */ }

Prevention

When it happens

Trigger: Chaining `.OrderBy(...).Skip(n).Take(m).Reverse()` or `.Take(m).Reverse()` on a Cosmos query, where Skip/Take precede Reverse in the translation order.

Common situations: Building a 'last N items' query by reversing a paged ascending result; porting a SQL pattern that relied on reverse-after-paging.

Related errors


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