Repository navigation
Adding .ConfigureAwait() to async query causes precompiled query generation to fail #37961
Copy link
Copy link
Closed
Copy link
Description
Bug description
An async query can have .ConfigureAwait() appended:
return await context.Blogs.FirstAsync(localCt).ConfigureAwait(false);
In that case, query precompilation fails with error:
System.InvalidOperationException: Query precompilation failed with errors:
QueryPrecompilationError { SyntaxNode = context.Blogs.FirstAsync(localCt), Exception = System.InvalidOperationException: Encountered unknown identifier name 'localCt', which doesn't correspond to a lambda parameter or captured variable
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitIdentifierName(IdentifierNameSyntax identifierName)
at Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitArgument(ArgumentSyntax argument, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitInvocationExpression(InvocationExpressionSyntax invocation)
at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Translate(SyntaxNode node, SemanticModel semanticModel)
at Microsoft.EntityFrameworkCore.Query.Internal.PrecompiledQueryCodeGenerator.ProcessSyntaxTree(SyntaxTree syntaxTree, SemanticModel semanticModel, IReadOnlyList`1 locatedQueries, List`1 precompilationErrors, String suffix, ISet`1 generatedFileNames, CancellationToken cancellationToken) }
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.PrecompileQueries(String outputDir, DbContext context, String suffix, IServiceProvider services, IReadOnlyDictionary`2 memberAccessReplacements, ISet`1 generatedFileNames)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String suffix, Boolean scaffoldModel, Boolean precompileQueries, DbContext context, Boolean optimizeAllInAssembly, Boolean nativeAot, List`1 generatedFiles, HashSet`1 generatedFileNames)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String contextTypeName, String suffix, Boolean scaffoldModel, Boolean precompileQueries, Boolean nativeAot)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContextImpl(String outputDir, String modelNamespace, String contextType, String suffix, Boolean scaffoldModel, Boolean precompileQueries, Boolean nativeAot)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContext.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Precompilation succeeds if parameterless .FirstAsync() is used or if .ConfigureAwait() call is separated from the query:
var task = context.Blogs.FirstAsync(localCt);
return await task.ConfigureAwait(false);
See attached project with minimal example.
Can be reproduced with:
> dotnet publish --ucr --sc
Your code
--- Model.cs
public class Blog
{
public int Id { get; set; }
}
--- Context.cs
using Microsoft.EntityFrameworkCore;
public class Context : DbContext
{
public DbSet<Blog> Blogs { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlite("Data Source=tmp.db");
}
}
--- Program.cs
using Microsoft.EntityFrameworkCore;
public static class Program
{
public static async Task<int> Main(string[] args)
{
var cts = new CancellationTokenSource();
_ = await QueryAsync(cts.Token);
return 0;
}
private static async Task<Blog> QueryAsync(CancellationToken ct)
{
await using var context = new Context();
var localCt = ct;
// var task = context.Blogs.FirstAsync(localCt);
// return await task.ConfigureAwait(false);
return await context.Blogs.FirstAsync(localCt).ConfigureAwait(false);
}
}Stack traces
Verbose output
> dotnet ef dbcontext optimize --output-dir Generated --nativeaot --precompile-queries --verbose
Using project '/workspaces/ef-play/confawait/confawait.csproj'.
Using startup project '/workspaces/ef-play/confawait/confawait.csproj'.
dotnet msbuild /getProperty:ProjectName /getProperty:AssemblyName /getProperty:DesignAssembly /getProperty:Language /getProperty:OutputPath /getProperty:PlatformTarget /getProperty:ProjectAssetsFile /getProperty:ProjectDir /getProperty:RootNamespace /getProperty:RuntimeFrameworkVersion /getProperty:TargetFileName /getProperty:TargetFrameworkMoniker /getProperty:Nullable /getProperty:TargetFramework /getProperty:TargetPlatformIdentifier /getProperty:Platform /t:ResolvePackageAssets /getItem:RuntimeCopyLocalItems /workspaces/ef-play/confawait/confawait.csproj
dotnet msbuild /getProperty:ProjectName /getProperty:AssemblyName /getProperty:DesignAssembly /getProperty:Language /getProperty:OutputPath /getProperty:PlatformTarget /getProperty:ProjectAssetsFile /getProperty:ProjectDir /getProperty:RootNamespace /getProperty:RuntimeFrameworkVersion /getProperty:TargetFileName /getProperty:TargetFrameworkMoniker /getProperty:Nullable /getProperty:TargetFramework /getProperty:TargetPlatformIdentifier /getProperty:Platform /t:ResolvePackageAssets /getItem:RuntimeCopyLocalItems /workspaces/ef-play/confawait/confawait.csproj
Build started...
dotnet build /workspaces/ef-play/confawait/confawait.csproj /verbosity:quiet /nologo /p:PublishAot=false /p:EFOptimizeContext=false
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:04.87
Build succeeded.
dotnet exec --depsfile /workspaces/ef-play/confawait/bin/Debug/net11.0/confawait.deps.json --additionalprobingpath /root/.nuget/packages --runtimeconfig /workspaces/ef-play/confawait/bin/Debug/net11.0/confawait.runtimeconfig.json /root/.dotnet/tools/.store/dotnet-ef/11.0.0-preview.1.26104.118/dotnet-ef/11.0.0-preview.1.26104.118/tools/net10.0/any/tools/net10.0/any/ef.dll dbcontext optimize --output-dir Generated --nativeaot --precompile-queries --assembly /workspaces/ef-play/confawait/bin/Debug/net11.0/confawait.dll --project /workspaces/ef-play/confawait/confawait.csproj --startup-assembly /workspaces/ef-play/confawait/bin/Debug/net11.0/confawait.dll --startup-project /workspaces/ef-play/confawait/confawait.csproj --project-dir /workspaces/ef-play/confawait/ --root-namespace confawait --language C# --framework net11.0 --design-assembly /root/.nuget/packages/microsoft.entityframeworkcore.design/11.0.0-preview.2.26159.112/lib/net11.0/Microsoft.EntityFrameworkCore.Design.dll --nullable --working-dir /workspaces/ef-play/confawait --verbose
Query precompilation is an experimental feature and should be used with caution.
NativeAOT support is experimental and can change in the future.
Using assembly 'confawait'.
Using startup assembly 'confawait'.
Using application base '/workspaces/ef-play/confawait/bin/Debug/net11.0'.
Using working directory '/workspaces/ef-play/confawait'.
Using root namespace 'confawait'.
Using project directory '/workspaces/ef-play/confawait/'.
Remaining arguments: .
Finding DbContext classes...
Using environment 'Development'.
Finding IDesignTimeDbContextFactory implementations...
Finding DbContext classes in the project...
Found DbContext 'Context'.
Finding application service provider in assembly 'confawait'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Using context 'Context'.
Finding design-time services referenced by assembly 'confawait'...
Finding design-time services referenced by assembly 'confawait'...
No referenced design-time services were found.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.Sqlite'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.Sqlite'.
Finding IDesignTimeServices implementations in assembly 'confawait'...
No design-time services were found.
Successfully generated a compiled model, it will be discovered automatically, but you can also call 'options.UseModel(ContextModel.Instance)'. Run this command again when the model is modified.
'Context' disposed.
System.InvalidOperationException: Query precompilation failed with errors:
QueryPrecompilationError { SyntaxNode = context.Blogs.FirstAsync(localCt), Exception = System.InvalidOperationException: Encountered unknown identifier name 'localCt', which doesn't correspond to a lambda parameter or captured variable
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitIdentifierName(IdentifierNameSyntax identifierName)
at Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitArgument(ArgumentSyntax argument, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitInvocationExpression(InvocationExpressionSyntax invocation)
at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Translate(SyntaxNode node, SemanticModel semanticModel)
at Microsoft.EntityFrameworkCore.Query.Internal.PrecompiledQueryCodeGenerator.ProcessSyntaxTree(SyntaxTree syntaxTree, SemanticModel semanticModel, IReadOnlyList`1 locatedQueries, List`1 precompilationErrors, String suffix, ISet`1 generatedFileNames, CancellationToken cancellationToken) }
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.PrecompileQueries(String outputDir, DbContext context, String suffix, IServiceProvider services, IReadOnlyDictionary`2 memberAccessReplacements, ISet`1 generatedFileNames)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String suffix, Boolean scaffoldModel, Boolean precompileQueries, DbContext context, Boolean optimizeAllInAssembly, Boolean nativeAot, List`1 generatedFiles, HashSet`1 generatedFileNames)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.Optimize(String outputDir, String modelNamespace, String contextTypeName, String suffix, Boolean scaffoldModel, Boolean precompileQueries, Boolean nativeAot)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContextImpl(String outputDir, String modelNamespace, String contextType, String suffix, Boolean scaffoldModel, Boolean precompileQueries, Boolean nativeAot)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OptimizeContext.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Query precompilation failed with errors:
QueryPrecompilationError { SyntaxNode = context.Blogs.FirstAsync(localCt), Exception = System.InvalidOperationException: Encountered unknown identifier name 'localCt', which doesn't correspond to a lambda parameter or captured variable
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitIdentifierName(IdentifierNameSyntax identifierName)
at Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitArgument(ArgumentSyntax argument, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node, Type expectedType)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.VisitInvocationExpression(InvocationExpressionSyntax invocation)
at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor`1.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Visit(SyntaxNode node)
at Microsoft.EntityFrameworkCore.Query.Internal.CSharpToLinqTranslator.Translate(SyntaxNode node, SemanticModel semanticModel)
at Microsoft.EntityFrameworkCore.Query.Internal.PrecompiledQueryCodeGenerator.ProcessSyntaxTree(SyntaxTree syntaxTree, SemanticModel semanticModel, IReadOnlyList`1 locatedQueries, List`1 precompilationErrors, String suffix, ISet`1 generatedFileNames, CancellationToken cancellationToken) }
EF Core version
10.0.3, 11.0.0-preview.2.26159.112
Database provider
Microsoft.EntityFrameworkCore.Sqlite
Target framework
.NET 10, .NET 11
Operating system
Ubuntu 24.04.4 LTS
IDE
No response
Reactions are currently unavailable
Activity
roji commentedon Mar 20, 2026
Thanks for raising this. I'm putting on the backlog as we're looking at better ways to support NativeAOT, but at some point we'll do a push and I'll take a look at fixing this.
nurullahturkoglu commentedon Oct 17, 2026
I'd like to fix this if it's open for a community PR, unless you'd rather keep it for the NativeAOT push.
The failure comes from Roslyn's data flow analysis.
CSharpToLinqTranslator.Translategets the captured variables fromAnalyzeDataFlow(node), but when the query is the receiver of an instance method call, the result hasSucceeded == falseand an emptyDataFlowsIn. The translator doesn't checkSucceeded, solocalCtends up as an unknown identifier.On the Roslyn side,
AbstractFlowPass.VisitCallwalks a chain of receiver calls in a loop without visiting each receiver, so the region is never entered.Async isn't required.
context.Blogs.Count(b => b.Id == id).ToString()andcontext.Blogs.Where(b => b.Id == id).ToList().Contains(blog)fail the same way, while extension method calls and property accesses on the result work.My plan is to retry the analysis on the parent expression when it fails, moving up until it succeeds. The parent's
DataFlowsInincludes the query's variables, and any extra ones don't matter because the translator only looks up identifiers inside the query.I have this working locally with two new tests in
PrecompiledQueryRelationalTestBase: the ConfigureAwait case from this issue and the syncToString()case. Both fail on main with the unknown identifier error and pass with the change, and EFCore.Design.Tests and the precompiled SQLite tests still pass. Does that sound OK? If so I'll open a PR.Fix precompiled queries that are the receiver of an instance method c…