dotnet/reactive · error · ArgumentNullException
source
Error message
source
What it means
The Last operator throws ArgumentNullException because the source IAsyncObservable<TSource> was null. Last emits the final element (optionally matching a predicate) of a sequence; a null source has no elements to observe, so the library fails fast at operator creation. Called via LastAsync/Last extension methods.
Solutions
- Pass a non-null IAsyncObservable<TSource> to Last/LastAsync.
- If the source may be absent, use AsyncObservable.Empty<TSource>() so Last surfaces an empty-sequence error through normal semantics instead.
- Trace and fix the upstream producer that returned null instead of a valid observable.
Example fix
// before var last = await maybeSource!.Last().FirstOrDefaultAsync(); // after var src = maybeSource ?? AsyncObservable.Empty<TSource>(); var last = await src.Last().FirstOrDefaultAsync();
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new ArgumentException("source observable must be non-null before calling Last", nameof(source)); Type guard
bool SourceReady<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try { var last = await source.Last(); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* fix the null producer or fall back to an empty observable */ } Prevention
- Have all observable-producing methods return Empty rather than null on failure.
- Enable C# nullable reference types to catch null sources at compile time.
- Null-check results of config/dictionary-based source lookups before chaining operators.
When it happens
Trigger: Calling source.Last() or source.LastAsync(predicate) where source is null — e.g. a repository method returned null instead of an empty observable, or a nullable field was never assigned.
Common situations: Chaining off a factory method that returns null on failure, conditional pipeline assembly where an upstream step was skipped, or dictionary/config lookups missing a key.
Related errors
- leftDurationSelector
- resultSelector
- right
- rightDurationSelector
- throw new ArgumentNullException(nameof(error));
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2039ab2b78e4c5a3.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Last.cs:18
// 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.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> LastAsync<TSource>(this IAsyncObservable<TSource> source) => Last(source);
public static IAsyncObservable<TSource> LastAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate) => Last(source, predicate);
public static IAsyncObservable<TSource> LastAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<bool>> predicate) => Last(source, predicate);
public static IAsyncObservable<TSource> Last<TSource>(this IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create(
source,
(source, observer) => source.SubscribeSafeAsync(AsyncObserver.Last(observer)));
}
public static IAsyncObservable<TSource> Last<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
return CreateAsyncObservable<TSource>.From(
source,
predicate,
static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Last(observer, predicate)));
}View on GitHub (pinned to 94b5d5ab91)