devlooped/moq · error · ArgumentException
No protected method . found whose signature is compatible…
Error message
No protected method {0}.{1} found whose signature is compatible with the provided arguments ({2}). What it means
ProtectedMock's string-based Setup/Verify for methods throws ArgumentException with Resources.MethodMissing when reflection cannot find a protected method with the given name whose parameters are compatible with the supplied argument values/expressions. The message lists T's name, the method name, and the formatted argument types so the signature mismatch is visible.
Solutions
- Match the argument expressions to the protected method's exact parameter types (use ItExpr.IsAny<T>() with the right type)
- Check the protected method's signature and pick the correct overload
- Ensure the method is protected/non-public instance, not public (public triggers a different guidance path)
- Cast literals to the exact parameter type expected
Example fix
// before (T: protected int Compute(int x))
mock.Protected().Setup<int>("Compute", ItExpr.IsAny<long>());
// after
mock.Protected().Setup<int>("Compute", ItExpr.IsAny<int>()); Defensive patterns
Strategy: validation
Validate before calling
static bool HasProtectedMethodWithArgs(Type target, string name, params Type[] argTypes) =>
target.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.Any(m => m.Name == name
&& m.GetParameters().Select(p => p.ParameterType).SequenceEqual(argTypes)); Try / catch
try { mock.Protected().Setup<int>("Compute", ItExpr.IsAny<int>()); }
catch (ArgumentException ex) when (ex.Message.StartsWith("No protected method")) { /* fix name or argument types */ } Prevention
- Match ItExpr.IsAny<T>() generic types to the exact protected parameter types
- Count and type-check arguments against the real protected signature
- Beware int/long and other implicit-conversion mismatches — reflection needs exact types
- For ref/out parameters, use the appropriate typed expression helpers
When it happens
Trigger: mock.Protected().Setup<int>("Compute", ItExpr.IsAny<long>()) where T has a Compute(int) protected method — the name exists but argument types (or argument count) do not match any protected overload.
Common situations: Passing wrong argument types (e.g. literal int vs long mismatch), wrong number of arguments for overloads, ref/out parameters supplied incorrectly, member renamed in a library upgrade while the call still 'succeeds' at name level.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Type does not have matching protected member
- ex.Message (re-thrown ArgumentException with paramName…
- Member . does not exist.
- "public bool ( ) in class .
- ex.Message from ReplaceDuck expression rewriting (rethrown…
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/89bf6a47a1891865.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Protected/ProtectedMock.cs:400
static void ThrowIfMethodMissing(string methodName, MethodInfo? method, object[] args)
#endif
{
if (method == null)
{
List<string> extractedTypeNames = new List<string>();
foreach (object o in args)
{
if (o is Expression expr)
{
extractedTypeNames.Add(expr.Type.GetFormattedName());
}
else
{
extractedTypeNames.Add(o.GetType().GetFormattedName());
}
}
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.MethodMissing,
typeof(T).Name,
methodName,
string.Join(
", ",
extractedTypeNames.ToArray())));
}
}
static void ThrowIfPublicMethod(MethodInfo method, string reflectedTypeName)
{
if (method.IsPublic)
{
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.MethodIsPublic,
reflectedTypeName,View on GitHub (pinned to 89a5be629c)