{"record":{"id":"9777ebb84aeb7ac8","repo":"devlooped/moq","slug":"unsupported-expression-0-constructorcallvisitor","errorCode":null,"errorMessage":"Unsupported expression: {0}","messagePattern":"Unsupported expression: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Moq/Expressions/Visitors/ConstructorCallVisitor.cs","lineNumber":57,"sourceCode":"\n        ConstructorInfo? constructor;\n        object[] arguments;\n\n#if NULLABLE_REFERENCE_TYPES\n        [return: NotNullIfNotNull(\"node\")]\n#endif\n        public override Expression? Visit(Expression? node)\n        {\n            switch (node?.NodeType)\n            {\n                case null:\n                    return null;\n                case ExpressionType.Lambda:\n                case ExpressionType.New:\n                case ExpressionType.Quote:\n                    return base.Visit(node);\n                default:\n                    throw new NotSupportedException(\n                        string.Format(\n                            CultureInfo.CurrentCulture,\n                            Resources.UnsupportedExpression,\n                            node.ToStringFixed()));\n            }\n        }\n\n        protected override Expression VisitNew(NewExpression node)\n        {\n            constructor = node.Constructor;\n\n            // Creates a lambda which uses the same argument expressions as the\n            // arguments contained in the NewExpression\n            var argumentExtractor = Expression.Lambda<Func<object[]>>(\n                                                                      Expression.NewArrayInit(\n                                                                       typeof(object),\n                                                                       node.Arguments.Select(a => Expression.Convert(a, typeof(object)))));\n            arguments = ExpressionCompiler.Instance.Compile(argumentExtractor).Invoke();","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Expressions/Visitors/ConstructorCallVisitor.cs#L39-L75","documentation":"Moq's expression visitor that extracts constructor-call arguments only supports Lambda, New, and Quote expression nodes. When a mock setup expression contains any other node type (e.g. a method call, member access, or constant used where a constructor call is expected), the visitor cannot interpret it and throws NotSupportedException. This is an internal guard indicating the setup expression does not match any supported pattern.","triggerScenarios":"Calling Mock.Of, mock.Setup, or expression parsing APIs with a lambda whose body contains an unsupported node — e.g. setup on a property getter expression, factory-method invocation, or compound expression that routes through ConstructorCallVisitor's default branch instead of a `new` expression.","commonSituations":"Developers write setup expressions Moq cannot decompose: setting up a non-virtual or static member, using a factory method instead of `new`, or passing complex multi-statement expressions. Also seen when refactoring setups after a library version change tightened expression parsing.","solutions":["Rewrite the setup expression so it is a simple constructor (`new`) expression or overridable member access that Moq supports.","Make the mocked member virtual/abstract/interface-based so it can be intercepted without the unsupported expression shape.","Split complex expressions into supported pieces or compute values outside the expression and pass them as locals/constants.","Inspect expression.ToStringFixed() in the message to identify the exact unsupported node and remove it."],"exampleFix":"// before\nvar mock = new Mock<Foo>();\nmock.Setup(f => f.Bar(CreateBaz())); // method call inside setup expression\n// after\nvar baz = CreateBaz();\nmock.Setup(f => f.Bar(baz)); // value computed outside the expression","handlingStrategy":"try-catch","validationCode":"bool isSupported = expr.Body is NewExpression || expr.Body is MemberExpression || expr.Body is MethodCallExpression;","typeGuard":"bool IsSupportedSetup(Expression e) => e is NewExpression || e is LambdaExpression l && (l.Body is NewExpression || l.Body is MemberExpression || l.Body is MethodCallExpression);","tryCatchPattern":"try { mock.Setup(f => f.Bar(CreateBaz())); }\ncatch (NotSupportedException ex) when (ex.Message.StartsWith(\"Unsupported expression\")) { /* rewrite setup: precompute values outside the expression */ throw new InvalidOperationException(\"Fix setup expression\", ex); }","preventionTips":["Keep setup lambdas simple: only member accesses on the mocked parameter.","Compute argument values outside the expression and pass locals.","Only mock virtual/abstract/interface members.","Read expression.ToStringFixed() in the message to identify the offending node."],"tags":["moq","expression-tree","unsupported-expression"],"backgroundTag":"unsupported-operation","analyzedSha":"89a5be629c752960fe403e95ff583e4ae6f00542","analyzedAt":"2026-09-16T05:31:39.496Z","contentChangedAt":"2026-09-16T05:31:39.496Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}