devlooped/moq · error · NotSupportedException

The new syntax allows you to pass the value in the…

Error message

The new syntax allows you to pass the value in the expression itself, like f => f.Value = 25. (thrown unconditionally via [Obsolete(..., true)])

What it means

This legacy Mock.SetupSet<T,T> extension (with a separate value parameter) is marked [Obsolete(..., true)] and throws NotSupportedException unconditionally. Modern Moq's instance SetupSet takes the value inside the expression, so this two-argument extension exists only to break compilation on old-style calls.

Solutions

  1. Switch to the instance syntax: mock.SetupSet(m => m.Value = 25).
  2. For flexible value matching use It.Is inside the assignment expression.
  3. Fix compile errors (error-level Obsolete) rather than suppressing with #pragma — the method always throws at runtime.

Example fix

// before
Mock.SetupSet(mock, f => f.Value, 25);
// after
mock.SetupSet(f => f.Value = 25);
Defensive patterns

Strategy: try-catch

Try / catch

try { Mock.SetupSet(mock, f => f.Value, 25); } catch (NotSupportedException) { mock.SetupSet(f => f.Value = 25); }

Prevention

When it happens

Trigger: Mock.SetupSet(mock, m => m.Value, 25) — calling the static extension overload in src/Moq/Obsolete/Mock.Generic.Legacy.cs:87 that accepts an explicit value argument.

Common situations: Ambiguity or migration errors after upgrading Moq where old call sites targeted the extension overload; old test utilities wrapping the legacy signature.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at src/Moq/Obsolete/Mock.Generic.Legacy.cs:87

        }
    }

    /// <summary>
    /// Contains obsolete API members as extension methods so that existing code continues to compile,
    /// but new code doesn't see them.
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class MockLegacyExtensions
    {
        /// <summary>
        /// Obsolete.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("The new syntax allows you to pass the value in the expression itself, like f => f.Value = 25.", true)]
        public static ISetupSetter<T, TProperty> SetupSet<T, TProperty>(this Mock<T> mock, Expression<Func<T, TProperty>> expression, TProperty value)
            where T : class
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Obsolete.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("Use the new syntax, which allows you to pass the value in the expression itself, mock.VerifySet(m => m.Value = 25);", true)]
        public static void VerifySet<T, TProperty>(this Mock<T> mock, Expression<Func<T, TProperty>> expression, TProperty value)
            where T : class
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Obsolete.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("Use the new syntax, which allows you to pass the value in the expression itself, mock.VerifySet(m => m.Value = 25, failMessage);", true)]

View on GitHub (pinned to 89a5be629c)