dotnet/efcore · error · NotSupportedException

Invocation over non-member access: {invocation}

Error message

Invocation over non-member access: {invocation}

What it means

For instance or extension method calls the translator expects the invocation node to sit on top of a member access (receiver.Method(...)). A NotSupportedException is thrown when invocation.Expression is not a MemberAccessExpressionSyntax, e.g. a delegate invoked directly as del().

Source

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

            throw new InvalidOperationException("Could not find symbol for method invocation: " + invocation);
        }

        // First, if the method return type is the user's DbContext type (e.g. DbContext local variable, or field/property), return a
        // constant over that DbContext type; the invocation can serve as the root for a LINQ query we can precompile.
        if (methodSymbol.ReturnType.Equals(_userDbContextSymbol, SymbolEqualityComparer.Default))
        {
            return Constant(_userDbContext);
        }

        var declaringType = ResolveType(methodSymbol.ContainingType);

        Expression? instance = null;
        if (!methodSymbol.IsStatic || methodSymbol.IsExtensionMethod)
        {
            // In normal method calls (the ones we support), the invocation node is composed on top of a member access
            if (invocation.Expression is not MemberAccessExpressionSyntax { Expression: var receiver })
            {
                throw new NotSupportedException($"Invocation over non-member access: {invocation}");
            }

            instance = Visit(receiver);
        }

        MethodInfo? methodInfo;

        if (methodSymbol.IsGenericMethod)
        {
            var originalDefinition = methodSymbol.OriginalDefinition;
            if (originalDefinition.ReducedFrom is not null)
            {
                originalDefinition = originalDefinition.ReducedFrom;
            }

            // To accurately find the right open generic method definition based on the Roslyn symbol, we need to create a mapping between
            // generic type parameter names (based on the Roslyn side) and .NET reflection Types representing those type parameters.
            // This includes both type parameters immediately on the generic method, as well as type parameters from the method's

View on GitHub (pinned to dbf9771522)

Solutions

  1. Call the target method directly rather than via a delegate variable
  2. Replace the delegate with a direct static or instance method call the translator can bind
  3. Hoist the delegate invocation out of the query into a precomputed captured value

Example fix

// before
Func<int, bool> ok = id => id > 0;
var q = ctx.Blogs.Where(b => ok(b.Id));
// after
var q = ctx.Blogs.Where(b => b.Id > 0);
Defensive patterns

Strategy: validation

Validate before calling

// Flag direct delegate invocations in precompiled query source.
static bool InvokesDelegate(string src)
    => System.Text.RegularExpressions.Regex.IsMatch(src, @"\b\w+\s*\(") && /* contains a Func/Action local */ false;
// Prefer: ensure no 'del(...)' style calls; only method calls on member access.

Prevention

When it happens

Trigger: Directly invoking a delegate or Func/Action variable (myDelegate(arg)), invoking the result of a parenthesized expression, or any invocation whose receiver is not a member-access expression.

Common situations: Storing a Func<T,bool> in a local and invoking it inside a precompiled query; calling through a delegate field/property; invoking a method group converted to a delegate.

Related errors


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