dotnet/efcore · error · NotSupportedException
Can't translate method
Error message
Can't translate method '{call.Method.Name}' which has no declaring type What it means
Thrown by LinqToCSharpSyntaxTranslator.VisitMethodCall when call.Method.DeclaringType is null. Reflection's MethodBase.DeclaringType is null only for global methods (and a few exotic cases); the translator needs a declaring type to render either a static receiver or an instance receiver expression, so a method with no declaring type cannot be translated.
Solutions
- Identify where the null-DeclaringType MethodInfo came from (DynamicMethod, reflection emit) and replace it with a normal MethodInfo on a real type.
- Wrap the call so the target method is a static/instance method on a concrete type whose DeclaringType is non-null.
- If the call truly is a global method, host it as a static method on a helper type and rewrite the tree to call that.
Example fix
// before — DynamicMethod with no declaring type inserted into a tree
DynamicMethod dm = new("Foo", typeof(int), new[] { typeof(int) });
// ... emit IL ...
var call = Expression.Call(dm.GetMethodInfo(), arg);
// after — host the same logic as a static method on a real type
public static class Helpers { public static int Foo(int x) => /* ... */; }
var call = Expression.Call(
typeof(Helpers), nameof(Helpers.Foo), null, arg); Defensive patterns
Strategy: validation
Validate before calling
// Reject MethodCallExpressions whose method has no declaring type.
using System.Linq.Expressions;
using System.Reflection;
bool HasNoDeclaringTypeCall(Expression e)
{
bool bad = false;
new CallChecker(c => { if (c.Method.DeclaringType is null) bad = true; }).Visit(e);
return bad;
}
class CallChecker(Action<MethodCallExpression> onCall) : ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression c) { onCall(c); return base.VisitMethodCall(c); }
} Type guard
static bool MethodHasDeclaringType(MethodCallExpression c)
=> c.Method.DeclaringType is not null; Prevention
- Avoid wrapping DynamicMethod or global-method MethodInfos inside expression trees.
- Host any global method as a static method on a real type and call that. Pre-scan trees for null-DeclaringType methods before translation.
When it happens
Trigger: An expression tree invokes a method whose MethodInfo reports a null DeclaringType — global-scope methods from dynamic assemblies, certain DynamicMethod bindings, or hand-crafted DynamicMethod-based MethodInfos inserted into a tree.
Common situations: DynamicMethod or other reflection-emit scenarios where MethodInfo.DeclaringType is null; building expression trees around global functions; malformed MethodInfo wrappers from third-party IL emit libraries.
Related errors
- Anonymous type creation without members
- Compound assignment of private property not yet supported
- Private static field access
- Private static field assignment
- BinaryExpression with
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/4dc410ee54180a12.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:1930
}
Result =
ElementAccessExpression(Translate<ExpressionSyntax>(index.Object!))
.WithArgumentList(
BracketedArgumentList(
SingletonSeparatedList(
Argument(
Translate<ExpressionSyntax>(index.Arguments.Single())))));
return index;
}
/// <inheritdoc />
protected override Expression VisitMethodCall(MethodCallExpression call)
{
if (call.Method.DeclaringType is null)
{
throw new NotSupportedException($"Can't translate method '{call.Method.Name}' which has no declaring type");
}
using var _ = ChangeContext(ExpressionContext.Expression);
var arguments = TranslateMethodArguments(call.Method.GetParameters(), call.Arguments);
// For generic methods, we check whether the generic type arguments are inferrable (e.g. they all appear in the parameters), and
// only explicitly specify the arguments if not. Note that this isn't just for prettier code: anonymous types cannot be explicitly
// named in code.
SimpleNameSyntax methodIdentifier;
if (!call.Method.IsGenericMethod || GenericTypeParameterAreInferrable())
{
methodIdentifier = IdentifierName(call.Method.Name);
}
else
{
Check.DebugAssert(
call.Method.GetGenericArguments().All(ga => !ga.IsAnonymousType()),View on GitHub (pinned to 3a2006ef56)