dotnet/reactive · error · ArgumentNullException
nameof(source)
Error message
nameof(source)
What it means
This is an ArgumentNullException thrown by AsyncObservable.Finally when the source observable is null. Finally attaches a guaranteed-invoked Action after the source terminates, and composition requires a real source to subscribe to, so a null source fails immediately at the call site.
Solutions
- Ensure the source observable is non-null before calling Finally
- Fix the factory/lookup that returned null
- Guard optional sources: source?.Finally(action) ?? emptyObservable, or check null explicitly
Example fix
// before
var tracked = source.Finally(() => Console.WriteLine("done")); // source null
// after
var tracked = source?.Finally(() => Console.WriteLine("done")) ?? AsyncObservable.Empty<TSource>(); Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new ArgumentNullException(nameof(source)); var tracked = source.Finally(finallyAction);
Type guard
bool HasSource<TSource>(IAsyncObservable<TSource> s) => s is not null;
Try / catch
try { var tracked = source.Finally(finallyAction); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* substitute an empty observable or skip wiring */ } Prevention
- Ensure source-producing methods never return null; return Empty<TSource>() instead
- Also validate finallyAction is non-null — Finally checks it too
- Use source?.Finally(action) patterns for optional sources
When it happens
Trigger: Calling source.Finally(action) where source is null — e.g. chained off a method that returned null, a registry lookup that missed, or an expression evaluated on an uninitialized observable.
Common situations: Cleanup wiring around streams that may be absent; refactoring where the source factory became nullable; pipelines built from config where a source key was missing.
Related errors
- nameof(source)
- source
- Value cannot be null. (Parameter 'disposable1')
- Value cannot be null. (Parameter 'disposable2')
- Value cannot be null. (Parameter 'source')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/dad250ad09a76b2b.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Finally.cs:15
// 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.Reactive.Disposables;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Finally<TSource>(this IAsyncObservable<TSource> source, Action finallyAction)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (finallyAction == null)
throw new ArgumentNullException(nameof(finallyAction));
return Create(
source,
finallyAction,
static async (source, finallyAction, observer) =>
{
var subscription = await source.SubscribeSafeAsync(observer).ConfigureAwait(false);
return AsyncDisposable.Create(async () =>
{
try
{
await subscription.DisposeAsync().ConfigureAwait(false);
}
finally
{View on GitHub (pinned to 94b5d5ab91)