dotnet/reactive · error · ArgumentNullException
source (Parameter 'source')
Error message
source (Parameter 'source')
What it means
The ToObservable(this IAsyncAction source) extension converts a WinRT IAsyncAction into an IObservable<Unit> that completes when the async action completes; it throws ArgumentNullException when 'source' is null. Rx needs the actual WinRT async object to attach its AsyncActionCompletedHandler, so a null source cannot be bridged.
Solutions
- Ensure the IAsyncAction is non-null before calling ToObservable; fix the producing method to always return a valid action.
- Guard the call: if (source != null) { ... ToObservable() ... } else return Observable.Empty<Unit>();
- If the producer may return null by design, wrap it in Observable.Defer and check inside.
Example fix
// before
IAsyncAction action = GetAction(); // may be null
var obs = action.ToObservable();
// after
var obs = GetAction() is IAsyncAction action
? action.ToObservable()
: Observable.Empty<Unit>(); Defensive patterns
Strategy: validation
Validate before calling
// csharp
if (source == null)
return Observable.Empty<Unit>();
var obs = source.ToObservable(); Type guard
// csharp bool IsBridgable(IAsyncAction source) => source is not null;
Try / catch
// csharp
try { obs = source.ToObservable(); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { obs = Observable.Throw<Unit>(new InvalidOperationException("Async action was null")); } Prevention
- Never let WinRT interop methods return null IAsyncAction; return Task-based APIs or fail fast
- Use Observable.Defer to evaluate the source lazily and check for null at subscription time
- Keep nullable annotations on async-operation fields
When it happens
Trigger: Calling source.ToObservable() where source is a null IAsyncAction reference — e.g. a method returning IAsyncAction returned null, or a WinRT API returned a null result.
Common situations: Interoping with WinRT APIs that can return null async operations; calling the extension on the result of a factory that failed silently; storing the async action in a nullable field not yet assigned.
Related errors
- Value cannot be null. (Parameter 'end')
- end
- begin
- Value cannot be null. (Parameter 'functionAsync')
- Value cannot be null. (Parameter 'options')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/64b5f02403e6aac0.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Foundation/AsyncInfoExtensions.cs:30
/// Provides conversions from Windows Runtime asynchronous actions and operations to observable sequences.
/// </summary>
[CLSCompliant(false)]
public static class AsyncInfoObservableExtensions
{
#region IAsyncAction and IAsyncActionWithProgress
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's successful or exceptional completion.
/// </summary>
/// <param name="source">Asynchronous action to convert.</param>
/// <returns>An observable sequence that produces a unit value when the asynchronous action completes, or propagates the exception produced by the asynchronous action.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<Unit> ToObservable(this IAsyncAction source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return new AsyncInfoToObservableBridge<Unit, Unit>(
source,
static (iai, a) => ((IAsyncAction)iai).Completed += new AsyncActionCompletedHandler((iaa, status) => a(iaa, status)),
iai => Unit.Default,
onProgress: null,
progress: null,
multiValue: false
);
}
/// <summary>
/// Converts a Windows Runtime asynchronous action to an observable sequence, ignoring its progress notifications.
/// Each observer subscribed to the resulting observable sequence will be notified about the action's successful or exceptional completion.
/// </summary>
/// <typeparam name="TProgress">The type of the reported progress objects, which get ignored by this conversion.</typeparam>
/// <param name="source">Asynchronous action to convert.</param>View on GitHub (pinned to 94b5d5ab91)