{"record":{"id":"d15dae5f2629bcc1","repo":"dotnet/reactive","slug":"thrown-when-comparer-is-null-argumentnullexception-param","errorCode":null,"errorMessage":"Thrown when comparer is null (ArgumentNullException, param name: comparer)","messagePattern":"Thrown when comparer is null \\(ArgumentNullException, param name: comparer\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Ix.NET/Source/System.Interactive/System/Linq/Operators/Max.cs","lineNumber":25,"sourceCode":"namespace System.Linq\n{\n    public static partial class EnumerableEx\n    {\n\n#if !(REFERENCE_ASSEMBLY && NET6_0_OR_GREATER)\n        /// <summary>\n        /// Returns the maximum value in the enumerable sequence by using the specified comparer to compare values.\n        /// </summary>\n        /// <typeparam name=\"TSource\">Source sequence element type.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"comparer\">Comparer used to determine the maximum value.</param>\n        /// <returns>Maximum value in the sequence.</returns>\n        public static TSource Max<TSource>(this IEnumerable<TSource> source, IComparer<TSource> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return MaxByWithTies(source, x => x, comparer).First();\n        }\n#endif\n    }\n}\n","sourceCodeStart":7,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Ix.NET/Source/System.Interactive/System/Linq/Operators/Max.cs#L7-L32","documentation":"The comparer-based Max operator requires a non-null IComparer<TSource> to order elements. Passing a null comparer throws ArgumentNullException with paramName 'comparer' immediately at the call site, before enumeration.","triggerScenarios":"Calling source.Max(comparer) where the comparer argument is null, e.g. data.Max(null), or passing a comparer field/property that was never initialized.","commonSituations":"Storing a comparer in configuration/DI and getting null when it is not registered; conditionally constructing a comparer that ends up null; writing generic code that forwards a possibly-null comparer parameter.","solutions":["Pass a concrete comparer such as Comparer<TSource>.Default when no custom ordering is needed.","Null-check or default the comparer before the call: comparer ??= Comparer<TSource>.Default;","Fix the comparer's construction/registration (DI binding, factory) so it is never null."],"exampleFix":"// before\nvar max = data.Max(cfg.Comparer); // Comparer not configured -> null\n// after\nvar max = data.Max(cfg.Comparer ?? Comparer<T>.Default);","handlingStrategy":"validation","validationCode":"if (comparer is null) comparer = Comparer<TSource>.Default;\nvar max = source.Max(comparer);","typeGuard":"static IComparer<T> NonNull<T>(IComparer<T>? c) => c ?? Comparer<T>.Default;","tryCatchPattern":"try\n{\n    var max = source.Max(comparer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"comparer\")\n{\n    var max = source.Max(); // fall back to default comparison\n}","preventionTips":["Never pass possibly-null comparers; always apply ?? Comparer<T>.Default","Verify DI/configuration actually registered the comparer","Keep comparer fields initialized at construction time"],"tags":["argumentnull","linq","dotnet","ix-net","comparer"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}