dotnet/efcore · error · InvalidOperationException

Could not find symbol for method invocation

Error message

Could not find symbol for method invocation: {invocation}

What it means

Thrown by VisitInvocationExpression when Roslyn's GetSymbolInfo on a method invocation returns a null or non-IMethodSymbol. The translator needs the resolved method symbol to find the corresponding reflection MethodInfo and build a MethodCallExpression. Without the symbol, it cannot determine what method is being called, so it throws InvalidOperationException.

Solutions

  1. Ensure all assemblies referenced by the project containing the query are available to the precompilation pipeline (check project references and the --assembly parameter passed to CSharpToLinqTranslator.Load).
  2. If invoking a delegate variable, wrap the call in a named method or restructure to call the underlying method directly so Roslyn resolves it as a method symbol.
  3. Check for compilation diagnostics/errors in the project before precompilation — unresolved symbols here often stem from upstream compile errors.
  4. If the invocation targets a type in an external assembly, pass that assembly via the additionalAssembly parameter of Load().

Example fix

// before — delegate invocation, Roslyn returns no IMethodSymbol
Func<int, bool> pred = x => x > 5;
var query = ctx.Blogs.Where(b => pred(b.Id));

// after — inline or use a named method
var query = ctx.Blogs.Where(b => b.Id > 5);
Defensive patterns

Strategy: validation

Validate before calling

// Before precompiling, verify every method invocation resolves to a symbol
var unresolvedInvocations = querySyntaxTree.DescendantNodes()
    .OfType<InvocationExpressionSyntax>()
    .Where(i => semanticModel.GetSymbolInfo(i).Symbol is not IMethodSymbol);
if (unresolvedInvocations.Any())
    ReportError("One or more method invocations could not be resolved — check references");

Try / catch

// If you invoke the translator programmatically:
try { var expr = translator.Translate(node, semanticModel); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Could not find symbol for method invocation"))
{
    // Fallback: do not precompile this query, let it compile at runtime
    LogPrecompileSkipped(node, ex); 
}

Prevention

When it happens

Trigger: A precompiled query contains a method invocation that Roslyn cannot resolve to a symbol. Causes include: the invoked method doesn't exist (compile error elsewhere), the method is a dynamic invocation (dynamic keyword), the method is a delegate invocation (Func/Action called directly rather than via a named method), the compilation is missing assembly references, or the symbol resolution returned an ErrorSymbol.

Common situations: Calling a method from an assembly not referenced by the precompilation Compilation; invoking a delegate variable directly (`myFunc(arg)` instead of a named method); using dynamic dispatch; stale Roslyn compilation state after editing source files; missing NuGet package providing the extension method being called.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/f91c0d910ffa269d. Report an issue: GitHub.

Appendix: source

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

                        nameof(FormattableStringFactory.Create), [typeof(string), typeof(object[])])!,

                _ => _stringFormatMethod ??= typeof(string).GetMethod(nameof(string.Format), [typeof(string), typeof(object[])])!
            },
            Constant(formatBuilder.ToString()),
            NewArrayInit(typeof(object), arguments));
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override Expression VisitInvocationExpression(InvocationExpressionSyntax invocation)
    {
        if (_semanticModel.GetSymbolInfo(invocation).Symbol is not IMethodSymbol methodSymbol)
        {
            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}");

View on GitHub (pinned to 3a2006ef56)