dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'error')
Error message
Value cannot be null. (Parameter 'error')
What it means
UnsafeAsyncObserver.OnErrorAsync guards its error parameter and throws ArgumentNullException when the Exception argument is null. Passing null to signal an error is not allowed; observers must always receive a concrete Exception instance describing the failure. This is a per-call guard on the delivery path, unlike the constructor guards at lines 15-17.
Solutions
- Always pass a real Exception, e.g. new InvalidOperationException("unknown failure") when no better one exists
- Audit code that forwards exceptions to OnErrorAsync and ensure the variable cannot be null at the call site
- Wrap the forwarding call in a null check or use ex ?? new Exception(...) before calling
Example fix
// before
await observer.OnErrorAsync(lastException); // lastException may be null
// after
await observer.OnErrorAsync(lastException ?? new InvalidOperationException("An error occurred with no exception details.")); Defensive patterns
Strategy: validation
Validate before calling
if (error == null) error = new InvalidOperationException("Unspecified error"); Type guard
static bool HasException(Exception ex) => ex != null;
Try / catch
try { await observer.OnErrorAsync(ex); } catch (ArgumentNullException) { await observer.OnErrorAsync(new InvalidOperationException("null error supplied")); } Prevention
- Never signal errors with a null Exception; synthesize one if the cause is unknown
- Null-coalesce at forwarding points: OnErrorAsync(ex ?? new Exception(...))
- Avoid reassigning caught exception variables to null
When it happens
Trigger: Calling observer.OnErrorAsync(null) — e.g. forwarding an exception variable that was null, or a pipeline that synthesizes error notifications without an Exception instance.
Common situations: Bridging from another reactive/async library where errors can be signaled without an exception object; code paths where a caught exception was reassigned to null; logging middleware that nulls out the exception before forwarding.
Related errors
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- ArgumentNullException
- source
- observer
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/3b35315e630d7f39.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Internal/UnsafeAsyncObserver.cs:24
namespace System.Reactive
{
public class UnsafeAsyncObserver<T> : IAsyncObserver<T>
{
private readonly Func<T, ValueTask> _onNextAsync;
private readonly Func<Exception, ValueTask> _onErrorAsync;
private readonly Func<ValueTask> _onCompletedAsync;
public UnsafeAsyncObserver(Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync, Func<ValueTask> onCompletedAsync)
{
_onNextAsync = onNextAsync ?? throw new ArgumentNullException(nameof(onNextAsync));
_onErrorAsync = onErrorAsync ?? throw new ArgumentNullException(nameof(onErrorAsync));
_onCompletedAsync = onCompletedAsync ?? throw new ArgumentNullException(nameof(onCompletedAsync));
}
public ValueTask OnCompletedAsync() => _onCompletedAsync();
public ValueTask OnErrorAsync(Exception error) => _onErrorAsync(error ?? throw new ArgumentNullException(nameof(error)));
public ValueTask OnNextAsync(T value) => _onNextAsync(value);
}
}
View on GitHub (pinned to 94b5d5ab91)