dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'finallyAction')
Error message
Value cannot be null. (Parameter 'finallyAction')
What it means
Thrown by the generated AsyncQueryableEx.Finally extension when finallyAction is null. The action is embedded into the expression tree as Expression.Constant(finallyAction, typeof(Action)), which cannot be null, so the library validates it up front.
Solutions
- Pass a real action, e.g. q.Finally(() => logger.Flush())
- If cleanup is optional, skip the Finally call when the action is null instead of passing null
- Default the action to a no-op: () => {}
- Check the DI/config registration that should provide the callback
Example fix
// before Action cleanup = GetCleanupHook(); // null when not configured var q = source.Finally(cleanup); // after var cleanup = GetCleanupHook(); var q = cleanup != null ? source.Finally(cleanup) : source;
Defensive patterns
Strategy: validation
Validate before calling
if (finallyAction is null) throw new ArgumentNullException(nameof(finallyAction));
Type guard
bool HasCleanup(Action? a) => a is not null;
Try / catch
try { query = source.Finally(action); }
catch (ArgumentNullException ex) when (ex.ParamName == "finallyAction") { throw new InvalidOperationException("Finally cleanup action was null", ex); } Prevention
- Only call Finally when a cleanup hook actually exists; conditionally apply it otherwise
- Default optional hooks to a no-op delegate
- Verify DI/event registrations that supply the cleanup callback
When it happens
Trigger: Calling Finally(source, null) or passing an Action field/delegate variable that was never assigned.
Common situations: Optional cleanup hooks configured externally where the hook was not registered; delegates wired via events or DI that remain null in some environments.
Related errors
- action (Parameter 'action')
- action (Parameter 'action')
- addHandler
- Argument cannot be null (Parameter name: functionAsync)
- Argument cannot be null (Parameter name: scheduler)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/9f6bf991da5e8b44.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs:1144
throw new ArgumentNullException(nameof(source));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
return source.Provider.CreateQuery<TSource>(Expression.Call(Expand__TSource__2__2(typeof(TSource)), source.Expression, selector));
}
private static MethodInfo? s_Finally__TSource__2__0;
private static MethodInfo Finally__TSource__2__0(Type TSource) =>
(s_Finally__TSource__2__0 ??
(s_Finally__TSource__2__0 = new Func<IAsyncQueryable<object>, Action, IAsyncQueryable<object>>(Finally<object>).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource);
public static IAsyncQueryable<TSource> Finally<TSource>(this IAsyncQueryable<TSource> source, Action finallyAction)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (finallyAction == null)
throw new ArgumentNullException(nameof(finallyAction));
return source.Provider.CreateQuery<TSource>(Expression.Call(Finally__TSource__2__0(typeof(TSource)), source.Expression, Expression.Constant(finallyAction, typeof(Action))));
}
private static MethodInfo? s_Finally__TSource__2__1;
private static MethodInfo Finally__TSource__2__1(Type TSource) =>
(s_Finally__TSource__2__1 ??
(s_Finally__TSource__2__1 = new Func<IAsyncQueryable<object>, Expression<Func<Task>>, IAsyncQueryable<object>>(Finally<object>).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource);
public static IAsyncQueryable<TSource> Finally<TSource>(this IAsyncQueryable<TSource> source, Expression<Func<Task>> finallyAction)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (finallyAction == null)
throw new ArgumentNullException(nameof(finallyAction));
return source.Provider.CreateQuery<TSource>(Expression.Call(Finally__TSource__2__1(typeof(TSource)), source.Expression, finallyAction));View on GitHub (pinned to 94b5d5ab91)