dotnet/reactive · error · ArgumentNullException
observer
Error message
observer
What it means
The AsyncObserver.TakeUntil<TSource, TUntil>(observer) factory throws ArgumentNullException because the downstream observer argument was null. This observer-level factory creates the paired (source, until) observers wired through an AsyncGate; it requires a non-null downstream IAsyncObserver to forward emissions to. The parameter name 'observer' identifies the null argument.
Solutions
- Pass the actual downstream IAsyncObserver you intend to forward to (e.g. the one obtained from CreateAsyncObserver or another operator factory).
- Check the composition order — create the downstream observer before calling AsyncObserver.TakeUntil.
- If writing a custom operator, assert observer != null at the entry of your SubscribeSafeAsync implementation to fail fast with a clearer message.
Example fix
// before var (srcObs, untilObs) = AsyncObserver.TakeUntil<int, object>(null); // after var downstream = AsyncObserver.Create<int>(onNextAsync: ...); var (srcObs, untilObs) = AsyncObserver.TakeUntil<int, object>(downstream);
Defensive patterns
Strategy: validation
Validate before calling
if (observer == null) throw new InvalidOperationException("downstream observer must be created before TakeUntil"); Type guard
bool HasObserver<T>(IAsyncObserver<T>? o) => o is not null;
Try / catch
try { var pair = AsyncObserver.TakeUntil<int, object>(observer); } catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* re-create downstream observer and retry composition */ } Prevention
- Always create the downstream observer (AsyncObserver.Create or upstream factory) before composing operator observers.
- In custom operators, assert non-null observers at the entry of SubscribeSafeAsync.
- Keep observer composition synchronous and ordered so references cannot be lost.
When it happens
Trigger: Calling AsyncObserver.TakeUntil<TSource, TUntil>(null) when composing custom observer pipelines.
Common situations: Building custom operators where the downstream observer comes from an upstream subscription that returned null; mis-ordered composition where the observer is created after it is passed; test scaffolding that forgot to instantiate the observer.
Related errors
- scheduler
- Value cannot be null. (Parameter 'onCompleted')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/443f116e3d9df822.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeUntil.cs:88
source,
(endTime, scheduler),
static async (source, state, observer) =>
{
var (sourceObserver, timer) = await AsyncObserver.TakeUntil(observer, state.endTime, state.scheduler).ConfigureAwait(false);
var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, timer);
});
}
}
public partial class AsyncObserver
{
public static (IAsyncObserver<TSource>, IAsyncObserver<TUntil>) TakeUntil<TSource, TUntil>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
var gate = new AsyncGate();
return
(
Create<TSource>(
async x =>
{
using (await gate.LockAsync().ConfigureAwait(false))
{
await observer.OnNextAsync(x).ConfigureAwait(false);
}
},
async ex =>
{
using (await gate.LockAsync().ConfigureAwait(false))
{
await observer.OnErrorAsync(ex).ConfigureAwait(false);View on GitHub (pinned to 94b5d5ab91)