{"record":{"id":"f674cf2867c25bb0","repo":"dotnet/efcore","slug":"the-provider-for-the-source-iqueryable-doesn-t-i","errorCode":null,"errorMessage":"The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.","messagePattern":"The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'\\. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs","lineNumber":249,"sourceCode":"    ///     An optional continuation token returned from a previous execution of this query via\n    ///     <see cref=\"CosmosPage{T}.ContinuationToken\" />. If <see langword=\"null\" />, retrieves query results from the start.\n    /// </param>\n    /// <param name=\"pageSize\">\n    ///     The maximum number of results in the returned <see cref=\"CosmosPage{T}\" />. The page may contain fewer results if the database\n    ///     did not contain enough matching results.\n    /// </param>\n    /// <param name=\"responseContinuationTokenLimitInKb\">Limits the length of continuation token in the query response.</param>\n    /// <param name=\"cancellationToken\">A <see cref=\"CancellationToken\" /> to observe while waiting for the task to complete.</param>\n    /// <returns>A <see cref=\"CosmosPage{T}\" /> containing at most <paramref name=\"pageSize\" /> results.</returns>\n    [Experimental(EFDiagnostics.PagingExperimental)]\n    public static Task<CosmosPage<TSource>> ToPageAsync<TSource>(\n        this IQueryable<TSource> source,\n        int pageSize,\n        string? continuationToken,\n        int? responseContinuationTokenLimitInKb = null,\n        CancellationToken cancellationToken = default)\n        => source.Provider is not IAsyncQueryProvider provider\n            ? throw new InvalidOperationException(CoreStrings.IQueryableProviderNotAsync)\n            : provider.ExecuteAsync<Task<CosmosPage<TSource>>>(\n                Expression.Call(\n                    instance: null,\n                    method: new Func<IQueryable<TSource>, int, string?, int?, CancellationToken, Task<CosmosPage<TSource>>>(ToPageAsync)\n                        .Method,\n                    arguments:\n                    [\n                        source.Expression,\n                        Expression.Constant(pageSize, typeof(int)),\n                        Expression.Constant(continuationToken, typeof(string)),\n                        Expression.Constant(responseContinuationTokenLimitInKb, typeof(int?)),\n                        Expression.Constant(default(CancellationToken), typeof(CancellationToken))\n                    ]),\n                cancellationToken);\n}\n","sourceCodeStart":231,"sourceCodeEnd":265,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs#L231-L265","documentation":"CosmosQueryableExtensions.ToPageAsync throws InvalidOperationException(CoreStrings.IQueryableProviderNotAsync) when source.Provider does not implement IAsyncQueryProvider. EF Core Cosmos requires the async query provider to translate and execute the paged query asynchronously; an IEnumerable-derived sequence, an in-memory List<T>.AsQueryable(), or a mock that returns a synchronous IQueryProvider will all fail this check.","triggerScenarios":"Calling ToPageAsync on List<T>.AsQueryable(); passing a query built from an in-memory IEnumerable; using a mock IQueryable whose Provider is a plain EnumerableQuery; calling ToPageAsync on an IQueryable exposed by a non-EF data source; composing the query after .AsEnumerable() which breaks the EF expression tree.","commonSituations":"Unit tests using List<T>.AsQueryable() to fake the Cosmos query; wrapping an EF query in a custom IQueryable that does not forward the EF provider; calling ToPageAsync on the wrong queryable after the query was already materialized for transformation.","solutions":["Call ToPageAsync directly on the EF Cosmos DbSet<T> or an IQueryable derived from it (where, orderBy, select keep it an EF queryable).","If you must unit-test paging, use the EF Core in-memory provider or a test double that implements IAsyncQueryProvider (e.g. TestQueryProvider from EF test infrastructure) - do not use List<T>.AsQueryable().","Remove any .AsEnumerable()/.ToList() that precedes the call; the EF provider must be reachable from the source passed in.","If you have a wrapper around IQueryable, expose the underlying EF queryable for paging operations rather than re-wrapping it."],"exampleFix":"// before - throws: provider is EnumerableQuery, not IAsyncQueryProvider\nvar rows = await InMemoryList.AsQueryable()\n    .ToPageAsync(pageSize: 50, continuationToken: token);\n\n// after - use the EF DbSet directly\nvar rows = await dbContext.Documents\n    .Where(d => d.PartitionKey == pk)\n    .ToPageAsync(pageSize: 50, continuationToken: token);","handlingStrategy":"type-guard","validationCode":"// Guard the call site so ToPageAsync is only invoked on EF queryables.\nstatic async Task<CosmosPage<T>> PageOrThrow<T>(IQueryable<T> source, int size, string? token)\n    where T : class\n{\n    if (source.Provider is not IAsyncQueryProvider)\n        throw new ArgumentException(\"ToPageAsync requires an EF Cosmos queryable.\", nameof(source));\n    return await source.ToPageAsync(size, token);\n}","typeGuard":"static bool SupportsAsyncPaging<T>(IQueryable<T> q) => q.Provider is IAsyncQueryProvider;","tryCatchPattern":"// Not generally recoverable; the fix is to pass a real EF queryable.\ntry { return await query.ToPageAsync(size, token); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"IAsyncQueryProvider\"))\n{ logger.PagingOnNonEfQuery(query.Expression.ToString()); throw; }","preventionTips":["Call ToPageAsync on a DbSet<T> or a query composed from it - not List<T>.AsQueryable().","For tests, use an EF in-memory provider or a TestQueryProvider implementing IAsyncQueryProvider.","Do not re-wrap EF queryables in custom IQueryables that drop the provider.","Document paging entry points so callers always pass EF queryables."],"tags":["ef-core","cosmos","async","paging","queryable"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}