dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'enumerableFactory')

Error message

Value cannot be null. (Parameter 'enumerableFactory')

What it means

Using<TSource,TResource> requires an enumerableFactory that maps the acquired resource to the sequence to produce. A null enumerableFactory is rejected eagerly with ArgumentNullException naming `enumerableFactory`, before any resource is acquired or disposed.

Solutions

  1. Provide the lambda: `Using(() => Open(), r => YieldFrom(r))`.
  2. Fix the composition layer that dropped/failed to load the delegate.
  3. Guard: `body ?? (r => Enumerable.Empty<TSource>())`.
  4. Keep the two delegates adjacent in the call to avoid argument misalignment during refactors.

Example fix

// before
Using(() => OpenHandle(), null)
// after
Using(() => OpenHandle(), handle => ReadItems(handle))
Defensive patterns

Strategy: validation

Validate before calling

if (enumerableFactory is null) throw new ArgumentNullException(nameof(enumerableFactory));

Type guard

static bool CanProject<T,TR>(Func<TR,IEnumerable<T>> f) where TR : IDisposable => f is not null;

Try / catch

try { var seq = Using(resFactory, enumFactory); }
catch (ArgumentNullException ex) when (ex.ParamName == "enumerableFactory") { /* supply default projection */ }

Prevention

When it happens

Trigger: Calling `Using(() => OpenResource(), null)`, commonly when the body lambda is built dynamically, loaded from config, or passed through an intermediary that lost it.

Common situations: Pipeline builders where per-resource logic is pluggable and a plugin failed to register, or refactors that accidentally dropped the lambda argument.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/1248c9e80ecc0c0b. Report an issue: GitHub.

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Using.cs:25

namespace System.Linq
{
    public static partial class EnumerableEx
    {
        /// <summary>
        /// Generates a sequence that's dependent on a resource object whose lifetime is determined by the sequence usage
        /// duration.
        /// </summary>
        /// <typeparam name="TSource">Source element type.</typeparam>
        /// <typeparam name="TResource">Resource type.</typeparam>
        /// <param name="resourceFactory">Resource factory function.</param>
        /// <param name="enumerableFactory">Enumerable factory function, having access to the obtained resource.</param>
        /// <returns>Sequence whose use controls the lifetime of the associated obtained resource.</returns>
        public static IEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
        {
            if (resourceFactory == null)
                throw new ArgumentNullException(nameof(resourceFactory));
            if (enumerableFactory == null)
                throw new ArgumentNullException(nameof(enumerableFactory));

            return UsingCore(resourceFactory, enumerableFactory);
        }

        private static IEnumerable<TSource> UsingCore<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
        {
            using var res = resourceFactory();

            foreach (var item in enumerableFactory(res))
            {
                yield return item;
            }
        }
    }
}

View on GitHub (pinned to 94b5d5ab91)