devlooped/moq · error · NotSupportedException

No constructor call could be found.

Error message

No constructor call could be found.

What it means

ExtractArgumentValues visits the lambda expecting its body to contain a NewExpression (constructor call). If the visitor finds no constructor call (visitor.constructor == null), it throws NotSupportedException 'No constructor call could be found.' The lambda must literally be something like `x => new Foo(x.A, x.B)`.

Solutions

  1. Change the lambda to directly instantiate the type: `x => new MyService(x.A, x.B)`.
  2. If construction goes through a factory method, refactor so the visitor receives the constructor call, or handle factory logic outside this API.
  3. Check for Convert/cast nodes wrapping the body and use an untyped lambda so the body is a plain NewExpression.
  4. Inspect the lambda string in your setup: it must start with `new `; if not, this visitor is the wrong tool for that expression.

Example fix

// before
var args = ConstructorCallVisitor.ExtractArgumentValues((Expression<Func<Dep, IService>>)(d => d.GetService()));
// after
var args = ConstructorCallVisitor.ExtractArgumentValues((Expression<Func<Dep, IService>>)(d => new Service(d.Logger)));
Defensive patterns

Strategy: type-guard

Validate before calling

static bool HasConstructorCall(LambdaExpression e) =>
    Unwrap(e.Body) is NewExpression;

Type guard

static Expression Unwrap(Expression e) =>
    e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.Quote } u ? Unwrap(u.Operand) : e;

Try / catch

try
{
    var values = ConstructorCallVisitor.ExtractArgumentValues(lambda);
}
catch (NotSupportedException ex) when (ex.Message.Contains("No constructor call"))
{
    // rewrite as x => new T(...) or use a different extraction path
}

Prevention

When it happens

Trigger: Passing a lambda whose body is not `new ...`: member accesses, method calls, `x => x.Service` factory-style expressions, object initializers compiled unexpectedly, or lambdas returning results of static factory methods instead of constructor invocation.

Common situations: Fixture/AutoFixture-style setups where a factory method is used instead of a constructor; lambdas written as `x => x.CreateFoo()`; expressions with converted/quoted bodies (Convert nodes) hiding the NewExpression; generic helpers passing `default` placeholder lambdas.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16). Data as JSON: /api/errors/604dd213c6fb570d. Report an issue: GitHub.

Appendix: source

Thrown at src/Moq/Expressions/Visitors/ConstructorCallVisitor.cs:34

    {
        /// <summary>
        /// Extracts the arguments from a lambda expression that calls a constructor.
        /// </summary>
        /// <param name="newExpression">The constructor expression.</param>
        /// <returns>Extracted argument values.</returns>
        public static object[] ExtractArgumentValues(LambdaExpression newExpression)
        {
            if (newExpression is null)
            {
                throw new ArgumentNullException(nameof(newExpression));
            }

            var visitor = new ConstructorCallVisitor();
            visitor.Visit(newExpression);

            if (visitor.constructor == null)
            {
                throw new NotSupportedException(Resources.NoConstructorCallFound);
            }

            return visitor.arguments;
        }

        ConstructorInfo? constructor;
        object[] arguments;

#if NULLABLE_REFERENCE_TYPES
        [return: NotNullIfNotNull("node")]
#endif
        public override Expression? Visit(Expression? node)
        {
            switch (node?.NodeType)
            {
                case null:
                    return null;
                case ExpressionType.Lambda:

View on GitHub (pinned to 89a5be629c)