dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'value')
Error message
Value cannot be null. (Parameter 'value')
What it means
PlatformEnlightenmentProvider.Current is the static injection point for Rx's platform enlightenment provider. Its setter rejects null with ArgumentNullException('value') because a null provider would break every internal enlightenment lookup (concurrency, timers, etc.).
Solutions
- Assign a valid IPlatformEnlightenmentProvider instance (e.g. new CurrentPlatformEnlightenmentProvider() or the test provider).
- Skip the assignment when the resolved value is null instead of writing it back.
- Cache the original provider and restore that reference, never null.
Example fix
// before
PlatformEnlightenmentProvider.Current = ResolveProvider();
// after
var provider = ResolveProvider();
if (provider != null) { PlatformEnlightenmentProvider.Current = provider; } Defensive patterns
Strategy: validation
Validate before calling
if (provider != null) { PlatformEnlightenmentProvider.Current = provider; } Type guard
bool IsValidProvider(IPlatformEnlightenmentProvider? p) => p is not null;
Try / catch
try { PlatformEnlightenmentProvider.Current = resolved; } catch (ArgumentNullException ex) when (ex.ParamName == "value") { /* fall back to default provider */ } Prevention
- Restore the original provider captured at test setup, never null, in teardown.
- Centralize provider assignment in one guarded helper.
When it happens
Trigger: Assigning PlatformEnlightenmentProvider.Current = null, typically in test teardown or DI setup code that resets a stored provider reference which was never initialized.
Common situations: Unit-test fixtures clearing static state between tests; host applications that read the provider from a service locator returning null before assignment.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/878b85ec0c4c9b28.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Internal/PlatformEnlightenmentProvider.cs:58
// NOTE TO MAINTAINERS
//
// Do *NOT* remove this mechanism which has been used beyond its original goal of supporting dependency injection when we were unifying
// the different Rx implementations as one Portable Library with platform-specific PlatformServices assemblies on top. Besides this, it
// has been used (and is still being used) for hosting scenarios where the host wants control over thread creation (cf. CAL), or other
// services (e.g. interception of query operators for logging, debugging, quota management, policy injection, etc.). Compat matters and
// lack thereof results in users getting stuck on older versions or having to resort to forking.
//
/// <summary>
/// (Infrastructure) Gets the current enlightenment provider. If none is loaded yet, accessing this property triggers provider resolution.
/// </summary>
/// <remarks>
/// This member is used by the Rx infrastructure and not meant for public consumption or implementation.
/// </remarks>
public static IPlatformEnlightenmentProvider Current
{
get => _current;
set => _current = value ?? throw new ArgumentNullException(nameof(value));
}
private static IPlatformEnlightenmentProvider CreatePlatformProvider() => new CurrentPlatformEnlightenmentProvider();
}
}
View on GitHub (pinned to 94b5d5ab91)