devlooped/moq · error · NotSupportedException

Out expression must evaluate to a constant value.

Error message

Out expression must evaluate to a constant value.

What it means

When setting up methods with out parameters via this Moq helper, each out argument's expression must evaluate to a constant (PartialEval must yield a ConstantExpression) so Moq can produce a concrete value to assign to the out parameter. Anything non-constant (method calls, closures, computations) triggers this NotSupportedException.

Solutions

  1. Replace the expression with a constant or a pre-computed local variable: var v = ComputeDefault(); setup.TheOutParameter(v)
  2. If a dynamic value is needed, use .Callback(...) or .Returns(...) to set the out parameter inside the delegate instead
  3. Use mock.Protected/direct delegate-based setup where out values are assigned in a callback

Example fix

// before
mock.Setup(m => m.TryParse(input, out DateTime.Now.AddMinutes(1)));
// after
var ts = DateTime.Now.AddMinutes(1);
mock.Setup(m => m.TryParse(input, out ts));
Defensive patterns

Strategy: validation

Validate before calling

// ensure out expressions are constants: assign to a local first
var outVal = ComputeDefault(); // then use 'out outVal'

Try / catch

try { mock.Setup(m => m.TryParse(input, out expr)); } catch (NotSupportedException) { /* pre-compute into a local and use 'out local' */ }

Prevention

When it happens

Trigger: setup.TheOutParameter(() => ComputeDefault()) or any out-expression whose partial evaluation is not a constant, e.g. referencing instance state or invoking methods.

Common situations: Trying to compute out values dynamically in the expression; passing a property or method-call result as the out default instead of a literal or captured constant.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Moq/SetupWithOutParameterSupport.cs:49

                {
                    invocation.Arguments[item.Key] = item.Value;
                }
            }
        }

        static List<KeyValuePair<int, object?>>? GetOutValues(IReadOnlyList<Expression> arguments, ParameterInfo[] parameters)
        {
            List<KeyValuePair<int, object?>>? outValues = null;
            for (int i = 0, n = parameters.Length; i < n; ++i)
            {
                var parameter = parameters[i];
                if (parameter.ParameterType.IsByRef)
                {
                    if ((parameter.Attributes & (ParameterAttributes.In | ParameterAttributes.Out)) == ParameterAttributes.Out)
                    {
                        if (arguments[i].PartialEval() is not ConstantExpression constant)
                        {
                            throw new NotSupportedException(Resources.OutExpressionMustBeConstantValue);
                        }

                        if (outValues == null)
                        {
                            outValues = new List<KeyValuePair<int, object?>>();
                        }

                        outValues.Add(new KeyValuePair<int, object?>(i, constant.Value));
                    }
                }
            }
            return outValues;
        }
    }
}

View on GitHub (pinned to 89a5be629c)