dotnet/reactive · error · InvalidOperationException
Strings_Linq.NO_ELEMENTS
Error message
Strings_Linq.NO_ELEMENTS
What it means
The Rx Max operator tracks whether the source sequence produced any element. When the observer's OnCompleted fires and no value was ever seen, the operator cannot produce a maximum, so it throws System.InvalidOperationException with the message Strings_Linq.NO_ELEMENTS ("Sequence contains no elements"). This mirrors the synchronous LINQ-to-Objects behavior of Enumerable.Max on an empty sequence: an aggregate over zero items is undefined rather than null.
Solutions
- Ensure the source can emit at least one value, or validate emptiness before aggregating.
- Use MaxOrDefault-style behavior by prepending a default: source.DefaultIfEmpty(0).Max().
- Use Observable.Empty detection first, e.g. Any(): await source.Any() before calling Max, or branch on it.
- For nullable-friendly semantics, aggregate with Scan + LastOrDefaultAsync or use System.Linq.AsyncEnumerable MaxAsync which throws only per its own contract.
- If the empty case is expected, catch InvalidOperationException around the subscription and supply a fallback value.
Example fix
// before
var max = await temperatures.Max(); // throws if temperatures is empty
// after
var max = await temperatures
.DefaultIfEmpty(double.NaN)
.Max(); // NaN sentinel instead of InvalidOperationException Defensive patterns
Strategy: validation
Validate before calling
bool hasAny = await source.Any(); if (!hasAny) return defaultValue; // avoids InvalidOperationException from Max var max = await source.Max();
Type guard
static async Task<bool> IsEmptyAsync<T>(this IObservable<T> source) =>
!await source.Any(); Try / catch
try
{
var max = await source.Max();
return max;
}
catch (InvalidOperationException ex) when (ex.Message == Strings_Linq.NO_ELEMENTS)
{
return defaultValue;
} Prevention
- Prefer DefaultIfEmpty(...) before Max/Min whenever the source may legitimately be empty.
- Check Any()/IsEmpty before aggregating in query pipelines.
- In tests, never Complete a Subject before publishing at least one value if Min/Max subscribe to it.
- Keep empty-window handling explicit in windowed/grouped aggregations.
When it happens
Trigger: Subscribing to Observable.Max over a source that completes without emitting any element — e.g. Observable.Empty<int>().Max(), a Where/filter that excludes every item, or an observable that completes immediately — and the anonymous observer in Max.cs (line ~78) reaches OnCompleted with _hasValue == false.
Common situations: Filtering a stream with a predicate that matches nothing (e.g. temperatures.Where(t => t > 100).Max()); querying a data feed that returns an empty batch; time-windowed aggregations where no events arrived during the window; race where the source completes before the first value due to cancellation or a hot sequence already finished.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Strings_Linq.NO_ELEMENTS
- Strings_Linq.NO_ELEMENTS
- Strings_Linq.NO_ELEMENTS
- Value cannot be null. (Parameter 'func')
- Source sequence doesn't contain any elements.
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/4e0e9ef6f78337c6.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable/Max.cs:78
if (comparison > 0)
{
_lastValue = value;
}
}
else
{
_hasValue = true;
_lastValue = value;
}
}
public override void OnCompleted()
{
if (!_hasValue)
{
try
{
throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
}
catch (Exception e)
{
ForwardOnError(e);
}
}
else
{
ForwardOnNext(_lastValue!);
ForwardOnCompleted();
}
}
}
private sealed class Null : _
{
private TSource? _lastValue;
View on GitHub (pinned to 94b5d5ab91)