dotnet/efcore · error · NotSupportedException

Async lambdas are not supported

Error message

Async lambdas are not supported

What it means

Thrown by VisitLambdaExpression when the lambda's AsyncKeyword is present (lambda.AsyncKeyword is not SyntaxKind.None). The translator cannot represent async semantics in a synchronous LINQ expression tree, so async lambdas are rejected outright. Part of EF Core's precompiled-query C#-to-LINQ translation.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1042

    /// </summary>
    public override Expression DefaultVisit(SyntaxNode node)
        => throw new NotSupportedException($"Unsupported syntax node of type '{node.GetType()}': {node}");

    private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambda, Type? expectedType = null)
    {
        if (lambda.ExpressionBody is null)
        {
            throw new NotSupportedException("Lambda with null expression body");
        }

        if (lambda.Modifiers.Any())
        {
            throw new NotSupportedException("Lambda with modifiers not supported: " + lambda.Modifiers);
        }

        if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
        {
            throw new NotSupportedException("Async lambdas are not supported");
        }

        var lambdaParameters = lambda switch
        {
            SimpleLambdaExpressionSyntax simpleLambda => SyntaxFactory.SingletonSeparatedList(simpleLambda.Parameter),
            ParenthesizedLambdaExpressionSyntax parenthesizedLambda => parenthesizedLambda.ParameterList.Parameters,

            _ => throw new UnreachableException()
        };

        var translatedParameters = new List<ParameterExpression>();
        foreach (var parameter in lambdaParameters)
        {
            if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol
                || ResolveType(parameterSymbol.Type) is not { } parameterType)
            {
                throw new InvalidOperationException("Could not found symbol for parameter lambda: " + parameter);
            }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Remove the 'async' keyword and any 'await' from the lambda; precompiled queries translate the expression tree synchronously.
  2. Use synchronous EF query APIs for the translated query path.

Example fix

// before
.Where(async x => await SomeCheckAsync(x))
// after
// move async logic out of the translatable predicate; keep the lambda synchronous
Defensive patterns

Strategy: validation

Validate before calling

foreach (var lambda in root.DescendantNodes().OfType<AnonymousFunctionExpressionSyntax>())
{
    if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
        throw new InvalidOperationException(
            $"Async lambda at {lambda.GetLocation()} cannot be translated; remove 'async'.");
}

Prevention

When it happens

Trigger: Translating precompiled query source containing an async lambda (async x => await ...).

Common situations: Mixing IQueryable sync extensions with async/await patterns inside a lambda; precompiling a query originally written with async lambda patterns.

Related errors


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