dotnet/efcore · error · InvalidOperationException

The provider for the source 'IQueryable' doesn't implement '

Error message

The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.

What it means

ToPageAsync requires the IQueryable's Provider to implement IAsyncQueryProvider (EF's provider). A plain LINQ provider — e.g. from List<T>.AsQueryable(), an in-memory IEnumerable, or a non-EF wrapper — does not, so the method throws InvalidOperationException via CoreStrings.IQueryableProviderNotAsync before executing.

Source

Thrown at src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs:249

    ///     An optional continuation token returned from a previous execution of this query via
    ///     <see cref="CosmosPage{T}.ContinuationToken" />. If <see langword="null" />, retrieves query results from the start.
    /// </param>
    /// <param name="pageSize">
    ///     The maximum number of results in the returned <see cref="CosmosPage{T}" />. The page may contain fewer results if the database
    ///     did not contain enough matching results.
    /// </param>
    /// <param name="responseContinuationTokenLimitInKb">Limits the length of continuation token in the query response.</param>
    /// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
    /// <returns>A <see cref="CosmosPage{T}" /> containing at most <paramref name="pageSize" /> results.</returns>
    [Experimental(EFDiagnostics.PagingExperimental)]
    public static Task<CosmosPage<TSource>> ToPageAsync<TSource>(
        this IQueryable<TSource> source,
        int pageSize,
        string? continuationToken,
        int? responseContinuationTokenLimitInKb = null,
        CancellationToken cancellationToken = default)
        => source.Provider is not IAsyncQueryProvider provider
            ? throw new InvalidOperationException(CoreStrings.IQueryableProviderNotAsync)
            : provider.ExecuteAsync<Task<CosmosPage<TSource>>>(
                Expression.Call(
                    instance: null,
                    method: new Func<IQueryable<TSource>, int, string?, int?, CancellationToken, Task<CosmosPage<TSource>>>(ToPageAsync)
                        .Method,
                    arguments:
                    [
                        source.Expression,
                        Expression.Constant(pageSize, typeof(int)),
                        Expression.Constant(continuationToken, typeof(string)),
                        Expression.Constant(responseContinuationTokenLimitInKb, typeof(int?)),
                        Expression.Constant(default(CancellationToken), typeof(CancellationToken))
                    ]),
                cancellationToken);
}

View on GitHub (pinned to dbf9771522)

Solutions

  1. Call ToPageAsync on a real EF DbSet<T>/IQueryable obtained from the DbContext.
  2. Do not call .AsQueryable() on an in-memory collection before ToPageAsync.
  3. In tests, use the EF in-memory or test double provider that implements IAsyncQueryProvider rather than List.AsQueryable().

Example fix

// before (in-memory list provider is not async)
var page = await _cache.AsQueryable()
    .ToPageAsync(pageSize: 20, continuationToken: token);

// after (real EF queryable)
var page = await _context.Items
    .ToPageAsync(pageSize: 20, continuationToken: token);
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the source provider supports async before paging.
if (source.Provider is not IAsyncQueryProvider)
    throw new InvalidOperationException("ToPageAsync requires an EF queryable (IAsyncQueryProvider).");
return await source.ToPageAsync(pageSize, token);

Type guard

static bool IsEfAsyncQueryable<T>(IQueryable<T> q) => q.Provider is IAsyncQueryProvider;

Try / catch

try { return await source.ToPageAsync(pageSize, token); }
catch (InvalidOperationException ex) when (ex.Message.Contains("IAsyncQueryProvider"))
{ throw new InvalidOperationException("Pass a DbSet/IQueryable from the DbContext, not an in-memory AsQueryable().", ex); }

Prevention

When it happens

Trigger: Calling ToPageAsync on myList.AsQueryable(); on a query built from an in-memory source; on a wrapped/fake IQueryable in a unit test that is not backed by an EF provider; composing over a DbSet that was replaced by a stub.

Common situations: Unit-testing Cosmos paging with a hand-rolled IQueryable; passing a materialized list back through a repository that returns IQueryable; using a mocking library that returns a non-async provider.

Related errors


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