{"record":{"id":"acd3f703ac2ab9c4","repo":"dotnet/reactive","slug":"plans","errorCode":null,"errorMessage":"plans","messagePattern":"plans","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs","lineNumber":95,"sourceCode":"\n        /// <summary>\n        /// Joins together the results from several patterns.\n        /// </summary>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>\n        /// <param name=\"provider\">Query provider used to construct the <see cref=\"IQbservable{T}\"/> data source.</param>\n        /// <param name=\"plans\">A series of plans created by use of the Then operator on patterns.</param>\n        /// <returns>An observable sequence with the results from matching several patterns.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"provider\"/> or <paramref name=\"plans\"/> is null.</exception>\n        public static IQbservable<TResult> When<TResult>(this IQbservableProvider provider, params QueryablePlan<TResult>[] plans)\n        {\n            if (provider == null)\n            {\n                throw new ArgumentNullException(nameof(provider));\n            }\n\n            if (plans == null)\n            {\n                throw new ArgumentNullException(nameof(plans));\n            }\n\n            return provider.CreateQuery<TResult>(\n                Expression.Call(\n                    null,\n                    new Func<IQbservableProvider, QueryablePlan<TResult>[], IQbservable<TResult>>(When).Method,\n                    Expression.Constant(provider, typeof(IQbservableProvider)),\n                    Expression.NewArrayInit(\n                        typeof(QueryablePlan<TResult>),\n                        plans.Select(p => p.Expression)\n                    )\n                )\n            );\n        }\n\n        /// <summary>\n        /// Joins together the results from several patterns.\n        /// </summary>","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs#L77-L113","documentation":"When<TResult>(params QueryablePlan<TResult>[] plans) requires a non-null plans array to match against; the method throws ArgumentNullException(\"plans\") when the array itself is null. Note the params array must exist even if empty (an empty array is accepted, null is not), because the plans are embedded into the Expression.Call for the remote/queryable When operator.","triggerScenarios":"Calling provider.When(null) explicitly, or passing a QueryablePlan<TResult>[] variable that is null (e.g. result of a failed lookup or uninitialized field).","commonSituations":"Dynamically building plans where the plan collection is assembled conditionally and ends up null at the call site; calling When with a null plans variable instead of an empty array.","solutions":["Pass at least one QueryablePlan, or an empty array instead of null: provider.When(Array.Empty<QueryablePlan<TResult>>()).","Null-check the plans collection and fall back to an empty plan set or an empty result query.","Fix the code that assembles the plans so it always produces a non-null array."],"exampleFix":"// before\nQueryablePlan<string>[] plans = BuildPlans(); // null\nvar result = provider.When(plans);\n// after\nQueryablePlan<string>[] plans = BuildPlans() ?? Array.Empty<QueryablePlan<string>>();\nvar result = provider.When(plans);","handlingStrategy":"validation","validationCode":"if (plans is null) plans = Array.Empty<QueryablePlan<TResult>>();\nvar result = provider.When(plans);","typeGuard":"bool HasPlans<TResult2>(QueryablePlan<TResult2>[]? p) => p is not null;","tryCatchPattern":"try { var result = provider.When(plans); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"plans\") { var result = provider.When(Array.Empty<QueryablePlan<TResult>>()); }","preventionTips":["Pass Array.Empty<T>() rather than null for empty plan sets","Assemble plans in a method that guarantees a non-null return","Distinguish 'no plans' (empty array) from 'unset' (null) in your code"],"tags":["argument-null","plans","when-operator","qbservable","rx","dotnet"],"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"}