{"record":{"id":"b1c5200ab956b7c3","repo":"devlooped/moq","slug":"value-cannot-be-null-parameter-value-expressionreconstructor","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'value')","messagePattern":"Value cannot be null\\. \\(Parameter 'value'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Moq/ExpressionReconstructor.cs","lineNumber":20,"sourceCode":"// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.\n\nusing System;\nusing System.Linq.Expressions;\n\nnamespace Moq\n{\n    /// <summary>\n    ///   A <see cref=\"ExpressionReconstructor\"/> reconstructs LINQ expression trees (<see cref=\"LambdaExpression\"/>)\n    ///   from <see cref=\"Action\"/> delegates. It is the counterpart to <see cref=\"ExpressionCompiler\"/>.\n    /// </summary>\n    abstract class ExpressionReconstructor\n    {\n        static ExpressionReconstructor instance = new ActionObserver();\n\n        public static ExpressionReconstructor Instance\n        {\n            get => instance;\n            set => instance = value ?? throw new ArgumentNullException(nameof(value));\n        }\n\n        protected ExpressionReconstructor()\n        {\n        }\n\n        /// <summary>\n        ///   Reconstructs a <see cref=\"LambdaExpression\"/> from the given <see cref=\"Action{T}\"/> delegate.\n        /// </summary>\n        /// <param name=\"action\">The <see cref=\"Action\"/> delegate for which to reconstruct a LINQ expression tree.</param>\n        /// <param name=\"ctorArgs\">Arguments to pass to a parameterized constructor of <typeparamref name=\"T\"/>. (Optional.)</param>\n        public abstract Expression<Action<T>> ReconstructExpression<T>(Action<T> action, object?[]? ctorArgs = null);\n    }\n}\n","sourceCodeStart":2,"sourceCodeEnd":35,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/ExpressionReconstructor.cs#L2-L35","documentation":"Moq exposes a replaceable ExpressionReconstructor.Instance, mirroring ExpressionCompiler.Instance. The setter enforces that a reconstructor is always available because delegate-based setups depend on it; assigning null throws ArgumentNullException for parameter 'value' to preserve that invariant.","triggerScenarios":"Assigning null to `ExpressionReconstructor.Instance`, e.g. during test cleanup `ExpressionReconstructor.Instance = null;` or when a factory/container yields null.","commonSituations":"Reset code attempting to clear the override; DI resolution failures producing null; copying configuration code from ExpressionCompiler usage where null-reset seemed acceptable.","solutions":["Assign a valid ExpressionReconstructor instance (the built-in default is an ActionObserver-derived instance).","Null-check the value before assignment; only swap when the new instance is non-null.","To restore defaults, cache the original value at startup and reassign that, never null.","Avoid resetting the static in teardowns unless you own a non-null replacement."],"exampleFix":"// before\nExpressionReconstructor.Instance = null; // teardown reset\n// after\nExpressionReconstructor.Instance = new ExpressionReconstructor(); // or restore saved default","handlingStrategy":"validation","validationCode":"var reconstructor = ResolveReconstructor();\nif (reconstructor == null) throw new InvalidOperationException(\"Resolved ExpressionReconstructor was null\");\nExpressionReconstructor.Instance = reconstructor;","typeGuard":"static bool CanInstall(ExpressionReconstructor? r) => r is not null;","tryCatchPattern":"try\n{\n    ExpressionReconstructor.Instance = candidate;\n}\ncatch (ArgumentNullException)\n{\n    // retain default instance\n}","preventionTips":["Treat Instance setters as non-nullable contracts everywhere in Moq","Save and restore the original instance instead of nulling in teardowns","Null-check container-resolved values before static assignment","Document static overrides in shared test infrastructure to avoid accidental resets"],"tags":["moq","null-argument","static-configuration","expression-reconstructor"],"backgroundTag":"null-argument","analyzedSha":"89a5be629c752960fe403e95ff583e4ae6f00542","analyzedAt":"2026-09-16T05:31:39.496Z","contentChangedAt":"2026-09-16T05:31:39.496Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}