devlooped/moq · error · ArgumentNullException
Value cannot be null. (Parameter 'value')
Error message
Value cannot be null. (Parameter 'value')
What it means
Moq allows replacing the expression compiler it uses via the static ExpressionCompiler.Instance property. The setter guards the library's invariant that a compiler must always be present; assigning null would break every later mock that compiles expressions, so it throws ArgumentNullException for parameter 'value' immediately.
Solutions
- Only assign a non-null ExpressionCompiler instance; store the previous value and restore that instead of null.
- Null-check the compiler obtained from your factory/DI container before assigning it to Instance.
- If you want default behavior, do not assign the property at all — it already defaults to Default; there is no need to reset via null.
- Wrap assignment in a guard that throws a descriptive error when the resolved compiler is null so the root cause (factory failure) surfaces.
Example fix
// before ExpressionCompiler.Instance = _container.Resolve<ExpressionCompiler>(); // may be null // after var compiler = _container.Resolve<ExpressionCompiler>(); if (compiler != null) ExpressionCompiler.Instance = compiler;
Defensive patterns
Strategy: validation
Validate before calling
var compiler = ResolveCompiler();
if (compiler == null) throw new InvalidOperationException("Resolved ExpressionCompiler was null");
ExpressionCompiler.Instance = compiler; Type guard
static bool CanSet(ExpressionCompiler? c) => c is not null;
Try / catch
try
{
ExpressionCompiler.Instance = resolved;
}
catch (ArgumentNullException)
{
// keep previous/default instance; log factory failure
} Prevention
- Never assign null to static Instance properties; restore a saved default instead
- Null-check DI/factory results before assigning
- Rely on the built-in Default unless you truly need a custom compiler
- Centralize static override logic in one guarded place
When it happens
Trigger: Assigning null to `ExpressionCompiler.Instance`, e.g. `ExpressionCompiler.Instance = null;` or passing a variable that is null at assignment time (uninitialized factory result, failed resolution, reset code).
Common situations: Custom compiler factories that return null on failure; DI containers resolving the compiler to null; cleanup/reset code that tries to 'clear' the instance by assigning null; test teardown ordering issues.
Related errors
- Value cannot be null. (Parameter 'value')
- Value cannot be null. (Parameter 'newExpression')
- callback (Argument is null)
- value (Argument is null)
- condition (Argument is null)
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/a87638a89807412f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/ExpressionCompiler.cs:31
/// </summary>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public abstract class ExpressionCompiler
{
static ExpressionCompiler instance = DefaultExpressionCompiler.Instance;
/// <summary>
/// The default <see cref="ExpressionCompiler"/> instance, which simply delegates to the framework's <see cref="LambdaExpression.Compile"/>.
/// </summary>
public static ExpressionCompiler Default => DefaultExpressionCompiler.Instance;
/// <summary>
/// Gets or sets the <see cref="ExpressionCompiler"/> instance that Moq uses to compile <see cref="Expression"/> (LINQ expression trees).
/// Defaults to <see cref="Default"/>.
/// </summary>
public static ExpressionCompiler Instance
{
get => instance;
set => instance = value ?? throw new ArgumentNullException(nameof(value));
}
/// <summary>
/// Initializes a new instance of the <see cref="ExpressionCompiler"/> class.
/// </summary>
protected ExpressionCompiler()
{
}
/// <summary>
/// Compiles the specified LINQ expression tree.
/// </summary>
/// <param name="expression">The LINQ expression tree that should be compiled.</param>
public abstract Delegate Compile(LambdaExpression expression);
/// <summary>
/// Compiles the specified LINQ expression tree.
/// </summary>View on GitHub (pinned to 89a5be629c)