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
- Replace the expression with a constant or a pre-computed local variable: var v = ComputeDefault(); setup.TheOutParameter(v)
- If a dynamic value is needed, use .Callback(...) or .Returns(...) to set the out parameter inside the delegate instead
- 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
- Always pass constants or pre-computed locals as out expressions
- Never call methods or access volatile state inside out expressions
- Use Callback/Returns to assign out values when dynamics are required
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
- Member is not supported for protected mocking.
- The return type of the last member shown above is not…
- No constructor call could be found.
- Unsupported expression
- Could not determine the correct positions for all argument…
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)