{"record":{"id":"abd26af0d248b6ee","repo":"devlooped/moq","slug":"can-t-set-return-value-for-void-method-0","errorCode":null,"errorMessage":"Can't set return value for void method {0}.","messagePattern":"Can't set return value for void method (.+?)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Moq/Protected/ProtectedMock.cs","lineNumber":451,"sourceCode":"        }\n\n        static void ThrowIfPublicSetter(PropertyInfo property, string reflectedTypeName)\n        {\n            if (property.CanWrite(out var setter) && setter.IsPublic)\n            {\n                throw new ArgumentException(string.Format(\n                    CultureInfo.CurrentCulture,\n                    Resources.UnexpectedPublicProperty,\n                    reflectedTypeName,\n                    property.Name));\n            }\n        }\n\n        static void ThrowIfVoidMethod(MethodInfo method)\n        {\n            if (method.ReturnType == typeof(void))\n            {\n                throw new ArgumentException(Resources.CantSetReturnValueForVoid);\n            }\n        }\n\n        static Type?[] ToArgTypes(object[] args)\n        {\n            if (args == null)\n            {\n                throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue);\n            }\n\n            var types = new Type?[args.Length];\n            for (int index = 0; index < args.Length; index++)\n            {\n                if (args[index] == null)\n                {\n                    throw new ArgumentException(Resources.UseItExprIsNullRatherThanNullArgumentValue);\n                }\n","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Protected/ProtectedMock.cs#L433-L469","documentation":"Moq's Protected() API throws this ArgumentException when you attempt to set up a return value for a method that has a void return type. Void methods have nothing to return, so a Returns/ReturnsAsync setup is meaningless and the library rejects it eagerly at setup time.","triggerScenarios":"Calling Protected().Setup(...) with a Returns(...) (or SetupSequence with returns) on a protected method whose MethodInfo.ReturnType is typeof(void), e.g. a protected void OnSomething() method.","commonSituations":"Copy-pasting a setup from a non-void method onto a protected event-raiser or callback-style void method; expecting Setup to also register a callback for void members.","solutions":["Remove the Returns(...) call; for void protected methods use Protected().Setup(...) with callbacks only (e.g. .Callback(...)) or just mock.Setup(...) raising events","If a value is needed, change the protected method signature to return a value, or verify the void call instead with Protected().Verify(...)"],"exampleFix":"// before\nmock.Protected().Setup(\"OnChanged\").Returns(true); // OnChanged is void\n// after\nmock.Protected().Setup(\"OnChanged\").Callback(() => changed = true);","handlingStrategy":"validation","validationCode":"if (methodInfo.ReturnType == typeof(void)) throw new InvalidOperationException(\"Do not call Returns on a void method: \" + methodInfo.Name);","typeGuard":null,"tryCatchPattern":"try { mock.Protected().Setup(\"OnChanged\").Returns(true); } catch (ArgumentException ex) { /* drop the Returns or use Callback */ }","preventionTips":["Only chain Returns/ReturnsAsync on members with non-void return types","Use .Callback/.Raises for void protected methods","Check the protected member signature before writing setups"],"tags":["moq","mocking","void-method","argument-exception"],"backgroundTag":"invalid-argument-value","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"}