devlooped/moq · error · ArgumentException

It is impossible to call the provided strongly-typed…

Error message

It is impossible to call the provided strongly-typed predicate due to the use of a type matcher. Provide a weakly-typed predicate with two parameters (object, Type) instead.

What it means

It.Is<TValue>(Expression<Func<TValue,bool>>) builds a matcher from a strongly-typed predicate. If TValue itself is or contains a type matcher (e.g. It.IsAnyType), the compiled predicate cannot be invoked safely, so Moq throws ArgumentException before creating the match. Moq requires the weakly-typed It.Is overload taking an (object, Type) predicate when type matchers are involved.

Solutions

  1. Use the two-parameter weakly-typed overload: It.Is((object v, Type t) => ...) instead of It.Is<TValue>(x => ...).
  2. If you know the concrete type, use It.Is<ConcreteType>(x => ...) instead of It.IsAnyType.
  3. Inside the weakly-typed predicate, cast the object argument to the expected runtime type before asserting.

Example fix

// before
mock.Verify(m => m.Send(It.Is<It.IsAnyType>(x => x.ToString() == "hi")));
// after
mock.Verify(m => m.Send(It.Is((object x, Type t) => x.ToString() == "hi")));
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof(TValue) == typeof(It.IsAnyType) || typeof(TValue).ContainsGenericParameters)
    useWeaklyTypedOverload = true; // use It.Is((object v, Type t) => ...) instead

Type guard

static bool UsesTypeMatcher<TValue>() => typeof(TValue).IsOrContainsTypeMatcher(); // then choose overload accordingly

Try / catch

try { expr = It.Is<TValue>(predicate); }
catch (ArgumentException) { expr = It.Is((object v, Type t) => predicate((TValue)v)); }

Prevention

When it happens

Trigger: It.Is<It.IsAnyType>(x => ...) or It.Is<object> containing It.IsAnyType nested in the value type — the Is<TValue> method checks typeof(TValue).IsOrContainsTypeMatcher() and throws ArgumentException naming the 'match' parameter.

Common situations: Trying to match generic method arguments or 'any type' parameters (e.g. verifying a call with a generic parameter) using the strongly-typed It.Is overload instead of the (object, Type) one; copy-pasting normal matcher code to a generic verification.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16). Data as JSON: /api/errors/7539144f3a78ca30. Report an issue: GitHub.

Appendix: source

Thrown at src/Moq/It.cs:143

        ///   the <c>Do</c> method is an even number.
        ///   <code>
        ///     mock.Setup(x =&gt; x.Do(It.Is&lt;int&gt;(i =&gt; i % 2 == 0)))
        ///         .Returns(1);
        ///   </code>
        /// </example>
        /// <example>
        ///   This example shows how to throw an exception if the argument to the method
        ///   is a negative number:
        ///   <code>
        ///     mock.Setup(x =&gt; x.GetUser(It.Is&lt;int&gt;(i =&gt; i &lt; 0)))
        ///         .Throws(new ArgumentException());
        ///   </code>
        /// </example>
        public static TValue Is<TValue>(Expression<Func<TValue, bool>> match)
        {
            if (typeof(TValue).IsOrContainsTypeMatcher())
            {
                throw new ArgumentException(Resources.UseItIsOtherOverload, nameof(match));
            }

            var thisMethod = (MethodInfo)MethodBase.GetCurrentMethod()!;
            var compiledMatchMethod = match.CompileUsingExpressionCompiler();

            return Match.Create<TValue>(
                argument => compiledMatchMethod.Invoke(argument),
                Expression.Lambda<Func<TValue>>(Expression.Call(thisMethod.MakeGenericMethod(typeof(TValue)), match)));
        }

        /// <summary>
        ///   Matches any value that satisfies the given predicate.
        ///   <para>
        ///     Use this overload when you specify a type matcher for <typeparamref name="TValue"/>.
        ///     The <paramref name="match"/> callback you provide will then receive the actual parameter type
        ///     as well as the invocation argument.
        ///   </para>
        /// </summary>

View on GitHub (pinned to 89a5be629c)