{"record":{"id":"30fdddfeb94f94c8","repo":"devlooped/moq","slug":"type-0-does-not-have-matching-protected-member-1","errorCode":null,"errorMessage":"Type {0} does not have matching protected member: {1}","messagePattern":"Type (.+?) does not have matching protected member: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Moq/Protected/ProtectedAsMock.cs","lineNumber":305,"sourceCode":"                    return FindCorrespondingProperty(duckProperty);\n                }\n                else\n                {\n                    throw new NotSupportedException();\n                }\n            }\n\n            MethodInfo FindCorrespondingMethod(MethodInfo duckMethod)\n            {\n                var candidateTargetMethods =\n                    this.targetType\n                    .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)\n                    .Where(ctm => IsCorrespondingMethod(duckMethod, ctm))\n                    .ToArray();\n\n                if (candidateTargetMethods.Length == 0)\n                {\n                    throw new ArgumentException(string.Format(Resources.ProtectedMemberNotFound, this.targetType, duckMethod));\n                }\n\n                Debug.Assert(candidateTargetMethods.Length == 1);\n\n                var targetMethod = candidateTargetMethods[0];\n\n                if (targetMethod.IsGenericMethodDefinition)\n                {\n                    var duckGenericArgs = duckMethod.GetGenericArguments();\n                    targetMethod = targetMethod.MakeGenericMethod(duckGenericArgs);\n                }\n\n                return targetMethod;\n            }\n\n            PropertyInfo FindCorrespondingProperty(PropertyInfo duckProperty)\n            {\n                var candidateTargetProperties =","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Protected/ProtectedAsMock.cs#L287-L323","documentation":"ProtectedAsMock's DuckReplacer maps a protected method called on the analog type to a matching protected method on the mocked type. When no method on T (searched with NonPublic | Instance bindings) satisfies IsCorrespondingMethod, this ArgumentException with Resources.ProtectedMemberNotFound ('Type {0} does not have matching protected member: {1}') is thrown. It surfaces to the caller wrapped with paramName 'expression'.","triggerScenarios":"mock.Protected().As<TAnalog>().Setup/Verify(a => a.Method(args)) where the mocked type T lacks a protected instance method with the same name, generic arity, and compatible parameter/return types.","commonSituations":"Test-double analog interface written by hand diverges from the real class; protected method overloads renamed after a refactor; signature drift after upgrading the mocked library (parameter type changed, added overload); mocking a derived type but the method is protected on the base with different accessibility.","solutions":["Confirm the method exists on T as a protected (or protected internal) instance method with an identical name and signature","Update TAnalog to declare the method exactly as it exists on T (name, parameter types, return type)","If the method became public, use the strong-typed Mock<T>.Setup/Verify instead of the Protected API","Verify you are mocking the concrete type that actually declares/overrides the protected member"],"exampleFix":"// before (T has Compute(int), analog declares Compute(long))\nmock.Protected().As<IAnalog>().Setup(a => a.Compute(2L));\n// after\nclass Analog { ... int Compute(int x); }\nmock.Protected().As<IAnalog>().Setup(a => a.Compute(2));","handlingStrategy":"validation","validationCode":"static bool HasProtectedMethod(Type target, string name, Type[] paramTypes) =>\n    target.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)\n          .Any(m => m.Name == name && m.GetParameters().Select(p => p.ParameterType).SequenceEqual(paramTypes));","typeGuard":null,"tryCatchPattern":"try { mock.Protected().As<IAnalog>().Setup(a => a.Compute(1)); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not have matching protected member\")) { /* align analog with T */ }","preventionTips":["Assert analog/target alignment in a unit test using reflection","Update TAnalog immediately when the mocked library changes protected signatures","Use nameof-style references where feasible to catch renames at compile time","Pin the mocked library version and review its changelog for protected-member changes"],"tags":["moq","reflection","protected-members","signature-mismatch"],"backgroundTag":"resource-not-found","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"}