dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'type')
Error message
Value cannot be null. (Parameter 'type')
What it means
The static-event overload FromEventPattern(Type type, string eventName) reflects over the given Type to find a static event. A null Type gives reflection no target, so Rx throws ArgumentNullException eagerly at the public API boundary rather than failing inside reflection.
Solutions
- Use typeof(SomeClass) directly for the static event's declaring type so the compiler verifies it.
- If the Type comes from a string, check Type.GetType/Assembly.GetType result for null before calling and throw a descriptive error.
- Load the required assembly before resolving the Type by name.
Example fix
// before
var t = asm.GetType(config.TypeName); // null if name is wrong
var obs = Observable.FromEventPattern(t, config.EventName);
// after
var t = asm.GetType(config.TypeName) ?? throw new InvalidOperationException($"Type {config.TypeName} not found");
var obs = Observable.FromEventPattern(t, config.EventName); Defensive patterns
Strategy: validation
Validate before calling
if (type is null) throw new InvalidOperationException($"Type '{typeName}' could not be resolved for static event subscription");
var obs = Observable.FromEventPattern(type, eventName); Type guard
static bool IsValidStaticEvent(Type type, string eventName) =>
type != null && type.GetEvent(eventName, BindingFlags.Static | BindingFlags.Public) != null; Try / catch
try
{
var obs = Observable.FromEventPattern(type, eventName);
}
catch (ArgumentNullException ex) when (ex.ParamName == "type")
{
// log that the type resolution failed; skip or rethrow with type name
} Prevention
- Use typeof(T) directly instead of Type variables resolved from strings.
- Null-check Assembly.GetType results before use.
- Ensure required assemblies are loaded before resolving types by name.
When it happens
Trigger: Calling Observable.FromEventPattern((Type)null, eventName) — the Type came from typeof on a missing generic argument, Assembly.GetType returning null for an unknown type name, or a Type variable not yet assigned.
Common situations: Reflection-based plugin loading where Assembly.GetType(name) returns null because the type name is wrong or the assembly isn't loaded; generics where typeof(T) is replaced by a nullable Type variable; config-driven static event subscription with a bad type name.
Related errors
- action (Parameter 'action')
- action (Parameter 'action')
- ArgumentNullException(nameof(scheduler))
- ArgumentNullException
- ArgumentNullException
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/21c729354df7b60a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Events.cs:859
/// <para>
/// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
/// making the Subscribe or Dispose call, respectively.
/// </para>
/// <para>
/// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
/// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
/// more concise and easier to understand.
/// </para>
/// </remarks>
/// <seealso cref="ToEventPattern"/>
#if HAS_TRIMMABILITY_ATTRIBUTES
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
#endif
public static IObservable<EventPattern<object>> FromEventPattern(Type type, string eventName)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (eventName == null)
{
throw new ArgumentNullException(nameof(eventName));
}
return s_impl.FromEventPattern(type, eventName);
}
/// <summary>
/// Converts a static .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
/// Each event invocation is surfaced through an OnNext message in the resulting sequence.
/// Reflection is used to discover the event based on the specified type and the specified event name.
/// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
/// </summary>
/// <param name="type">Type that exposes the static event to convert.</param>
/// <param name="eventName">Name of the event to convert.</param>View on GitHub (pinned to 94b5d5ab91)