dotnet/reactive · error · ArgumentNullException

source

Error message

source

What it means

TakeLastBuffer(source, count) validates the source observable and throws ArgumentNullException when it is null. As an extension method invoked on a null receiver, the guard fires inside the method rather than at the call site.

Solutions

  1. Ensure the source observable is created before calling TakeLastBuffer.
  2. Add a null check on the source at its construction point.
  3. Replace null-producing factory branches with a non-null Empty observable.

Example fix

// before
IAsyncObservable<int> source = Build(); // may be null
var buf = source.TakeLastBuffer(10);
// after
var source = Build() ?? AsyncObservable.Empty<int>();
var buf = source.TakeLastBuffer(10);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new ArgumentNullException(nameof(source));
source.TakeLastBuffer(count);

Type guard

bool HasSource<TSource>(IAsyncObservable<TSource> s) => s is not null;

Try / catch

try { var buf = source.TakeLastBuffer(count); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* substitute Empty source */ }

Prevention

When it happens

Trigger: source.TakeLastBuffer(10) where source is a null IAsyncObservable<TSource>, e.g. from a builder method that returned null.

Common situations: Factory/conditional composition returning null observables; assigning the result of a lookup that found nothing; missing earlier operator validation.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeLastBuffer.cs:16

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 

using System.Collections.Generic;
using System.Reactive.Concurrency;
using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<IList<TSource>> TakeLastBuffer<TSource>(this IAsyncObservable<TSource> source, int count)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (count < 0)
                throw new ArgumentOutOfRangeException(nameof(count));

            if (count == 0)
            {
                return Empty<IList<TSource>>();
            }

            return CreateAsyncObservable<IList<TSource>>.From(
                source,
                count,
                static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.TakeLastBuffer(observer, count)));
        }

        public static IAsyncObservable<IList<TSource>> TakeLastBuffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

View on GitHub (pinned to 94b5d5ab91)