{"record":{"id":"e108d08615c2a99c","repo":"devlooped/moq","slug":"resources-unsupportedexpression-formatted-with-expression","errorCode":null,"errorMessage":"Resources.UnsupportedExpression (formatted with expression)","messagePattern":"Resources\\.UnsupportedExpression \\(formatted with expression\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Moq/Mock.cs","lineNumber":743,"sourceCode":"                                               .SingleOrDefault(e => e.GetAddMethod(true) == implementingMethod)\n                             ?? throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,\n                                                                          Resources.SetupNotEventAdd,\n                                                                          part.Expression));\n\n                }\n                else if (method.IsEventRemoveAccessor())\n                {\n                    var implementingMethod = method.GetImplementingMethod(mock.Object.GetType());\n                    @event = implementingMethod.DeclaringType!.GetEvents(bindingFlags)\n                                               .SingleOrDefault(e => e.GetRemoveMethod(true) == implementingMethod)\n                             ?? throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,\n                                                                          Resources.SetupNotEventRemove,\n                                                                          part.Expression));\n\n                }\n                else\n                {\n                    throw new ArgumentException(\n                        string.Format(\n                            CultureInfo.CurrentCulture,\n                            Resources.UnsupportedExpression,\n                            expression));\n                }\n\n                if (mock.EventHandlers.TryGet(@event, out var handlers))\n                {\n                    var returnType = handlers.GetMethodInfo().ReturnType;\n                    if (returnType == typeof(Task) || returnType.FullName == \"System.Threading.Tasks.ValueTask\")\n                    {\n                        var invocationList = handlers.GetInvocationList();\n                        var tasks = new List<Task>(invocationList.Length);\n                        foreach (var handler in invocationList)\n                        {\n                            var returnValue = handler.InvokePreserveStack(arguments);\n                            if (returnValue is Task task)\n                            {","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Mock.cs#L725-L761","documentation":"Mock.Raise<T>(eventExpression, args) requires the lambda to be an event accessor expression (+= or -=). If the expression is anything else — a method call, property access, or plain member reference — Moq throws ArgumentException with Resources.UnsupportedExpression because it can only raise events through accessor syntax.","triggerScenarios":"Passing a non-accessor lambda to Raise, e.g. mock.Raise(x => x.MyMethod(), args) or mock.Raise(x => x.SomeProperty, value); any expression whose body is not an event add/remove assignment.","commonSituations":"Copy-paste between mock.Raise and mock.Verify/mocked member setups; misunderstanding that Raise targets events, not methods; typos where the += null part was omitted.","solutions":["Use event accessor syntax: mock.Raise(x => x.MyEvent += null, EventArgs.Empty, ...)","If you meant to configure a member, use mock.Setup(...) or mock.Verify(...) instead of Raise","If you meant to invoke a method on the mock, call it on mock.Object or mock.Raise only for delegate/event members","Check the lambda targets an event declared on an interface or non-sealed class"],"exampleFix":"// before\nmock.Raise(x => x.HandleOrder(order)); // method call, not an event accessor -> throws\n// after\nmock.Raise(x => x.OrderPlaced += null, new OrderEventArgs(order));","handlingStrategy":"validation","validationCode":"static bool IsEventAccessorLambda<T>(System.Linq.Expressions.Expression<Action<T>> e) =>\n    e.Body is System.Linq.Expressions.Expression assign &&\n    (assign.NodeType == System.Linq.Expressions.ExpressionType.AddAssign ||\n     assign.NodeType == System.Linq.Expressions.ExpressionType.SubtractAssign);\n// call before mock.Raise; if false, use Setup/Verify instead","typeGuard":"static bool IsEvent(System.Linq.Expressions.Expression<Action<T>> e, out string? eventName)\n{\n    eventName = null;\n    if (e.Body is System.Linq.Expressions.BinaryExpression b &&\n        (b.NodeType == System.Linq.Expressions.ExpressionType.AddAssign ||\n         b.NodeType == System.Linq.Expressions.ExpressionType.SubtractAssign) &&\n        b.Left is System.Linq.Expressions.MemberExpression me &&\n        me.Member is System.Reflection.EventInfo)\n    {\n        eventName = me.Member.Name;\n        return true;\n    }\n    return false;\n}","tryCatchPattern":"try\n{\n    mock.Raise(x => x.MyEvent += null, EventArgs.Empty);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"UnsupportedExpression\"))\n{\n    // correct the lambda to event accessor syntax or switch to Setup/Verify\n}","preventionTips":["Remember mock.Raise only accepts event accessor lambdas (e => e.Evt += null or -= null)","Use mock.Setup/mockedObject calls for method and property interactions","Validate the expression shape in shared test helpers before delegating to Raise"],"tags":["moq","unsupported-expression","raise","event"],"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"}