dotnet/reactive · error · ArgumentNullException

nameof(gate)

Error message

nameof(gate)

What it means

Synchronize<TSource>(source, object gate) throws ArgumentNullException when the gate object is null. The gate is the lock object on which outgoing observer calls are synchronized; Rx requires a concrete object to lock on and rejects null up front.

Solutions

  1. Pass a non-null lock object, e.g. a private readonly object _gate = new object();
  2. Initialize the gate in the field declaration or constructor rather than lazily.
  3. If no gate is needed, use the parameterless Synchronize() overload, which synchronizes on its own gate.

Example fix

// before
private object _gate; // never assigned
src.Synchronize(_gate); // ArgumentNullException
// after
private readonly object _gate = new object();
src.Synchronize(_gate);
Defensive patterns

Strategy: validation

Validate before calling

if (gate is null) throw new InvalidOperationException("Lock gate not initialized");
var synced = source.Synchronize(gate);

Type guard

static bool HasGate(object? gate) => gate is not null;

Try / catch

try { var s = source.Synchronize(gate); }
catch (ArgumentNullException ex) when (ex.ParamName == "gate") { log.Error("Gate object was null"); }

Prevention

When it happens

Trigger: Calling source.Synchronize(gate) with gate == null — e.g. a lazily-initialized lock field that was never created, or a gate passed through from an optional constructor parameter.

Common situations: Typical when the owning class's lock object is initialized in an Init/Start method that was not called, or when a null was supplied via DI as an optional gate.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Concurrency.cs:172

        /// <summary>
        /// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently, using the specified gate object.
        /// This overload is useful when writing n-ary query operators, in order to prevent concurrent callbacks from different sources by synchronizing on a common gate object.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="gate">Gate object to synchronize each observer call on.</param>
        /// <returns>The source sequence whose outgoing calls to observers are synchronized on the given gate object.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="gate"/> is null.</exception>
        public static IObservable<TSource> Synchronize<TSource>(this IObservable<TSource> source, object gate)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (gate == null)
            {
                throw new ArgumentNullException(nameof(gate));
            }

            return s_impl.Synchronize(source, gate);
        }

        #endregion
    }
}

View on GitHub (pinned to 94b5d5ab91)