dotnet/reactive · error · InvalidOperationException
Strings_Core.COMPLETED_NO_VALUE
Error message
Strings_Core.COMPLETED_NO_VALUE
What it means
OnCompletedNotification<T>.Value throws InvalidOperationException with Strings_Core.COMPLETED_NO_VALUE. An OnCompleted notification carries no value, so reading .Value is semantically invalid; Rx models this as an InvalidOperationException rather than returning default(T) to avoid silently propagating a meaningless value.
Solutions
- Check notification.Kind == NotificationKind.OnCompleted (or OnError) before reading Value.
- Pattern-match on the concrete type (OnNextNotification<T> vs OnCompletedNotification<T> / OnErrorNotification<T>).
- Use Accept with handlers instead of touching Value directly.
Example fix
// before var value = notification.Value; // after var value = notification.Kind == NotificationKind.OnNext ? notification.Value : default;
Defensive patterns
Strategy: type-guard
Validate before calling
if (notification.Kind != NotificationKind.OnNext) throw new InvalidOperationException("Value is only available on OnNext notifications");
var value = notification.Value; Type guard
static bool TryGetValue<T>(Notification<T> n, out T? value) { value = default; return n.Kind == NotificationKind.OnNext && (value = n.Value) is not null || n.Kind == NotificationKind.OnNext; } // safer: pattern-match concrete types Try / catch
try { value = notification.Value; } catch (InvalidOperationException ex) when (ex.Message.Contains("COMPLETED") || ex.Message.Contains("completed")) { value = default; } Prevention
- Always check notification.Kind before touching Value.
- Prefer pattern matching on OnNextNotification<T> / OnErrorNotification<T> / OnCompletedNotification<T>.
- Prefer Accept with handlers so value/completion branching is enforced by the API.
When it happens
Trigger: Accessing the Value property of a Notification<T> whose Kind is OnCompleted — typically without first checking notification.Kind or pattern-matching on the concrete notification type.
Common situations: Code that receives materialized notifications from a sequence, logs or serializes all notifications uniformly, and reads Value unconditionally; or unit-test assertions that inspect Value for every notification.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- AdvanceBy cannot be called when the scheduler is already…
- AdvanceTo cannot be called when the scheduler is already…
- Could not find instance event
- Could not find static event
- Disposable already assigned.
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2eee1b0ab4f78450.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Notification.cs:403
internal sealed class OnCompletedNotification : Notification<T>
{
/// <summary>
/// Complete notifications are stateless thus only one instance
/// can ever exist per type.
/// </summary>
internal static readonly Notification<T> Instance = new OnCompletedNotification();
/// <summary>
/// Constructs a notification of the end of a sequence.
/// </summary>
private OnCompletedNotification()
{
}
/// <summary>
/// Throws an <see cref="InvalidOperationException"/>.
/// </summary>
public override T Value { get { throw new InvalidOperationException(Strings_Core.COMPLETED_NO_VALUE); } }
/// <summary>
/// Returns <c>null</c>.
/// </summary>
public override Exception? Exception => null;
/// <summary>
/// Returns <c>false</c>.
/// </summary>
public override bool HasValue => false;
/// <summary>
/// Returns <see cref="NotificationKind.OnCompleted"/>.
/// </summary>
public override NotificationKind Kind => NotificationKind.OnCompleted;
/// <summary>
/// Returns the hash code for this instance.View on GitHub (pinned to 94b5d5ab91)