dotnet/reactive · error · InvalidOperationException
MORE_THAN_ONE_MATCHING_ELEMENT
Error message
MORE_THAN_ONE_MATCHING_ELEMENT
What it means
The predicate-based SingleAsync overload throws InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT) when a second element satisfying the predicate arrives after one was already matched, forwarding it via OnError. It enforces 'exactly one matching element' like LINQ's Single(predicate).
Solutions
- Tighten the predicate so exactly one element matches, or deduplicate upstream with Distinct/DistinctUntilChanged.
- Use FirstAsync(predicate) when only the first match is needed, or SingleOrDefaultAsync if zero-or-one is acceptable.
- Fix the underlying data/source so the uniqueness invariant actually holds.
Example fix
// before var active = await sessions.SingleAsync(s => s.IsActive); // after var active = await sessions.Where(s => s.IsActive).Take(1).FirstAsync();
Defensive patterns
Strategy: fallback
Try / catch
try { var v = await source.SingleAsync(x => x.IsActive); }
catch (InvalidOperationException) { var v = await source.Where(x => x.IsActive).FirstAsync(); } Prevention
- Tighten predicates so uniqueness holds, or deduplicate upstream.
- Use FirstAsync(predicate) when any match suffices.
- Enforce the underlying data invariant (e.g. single active record) at write time.
When it happens
Trigger: source.SingleAsync(x => predicate(x)) on a stream where two distinct OnNext values satisfy the predicate before completion.
Common situations: Selecting 'the' active record (e.g. current session, default profile) where data integrity allows several active rows; race conditions creating duplicates; a predicate written too loosely (e.g. status == Active matching stale rows).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Strings_Linq.NO_MATCHING_ELEMENTS
- Strings_Linq.NO_MATCHING_ELEMENTS
- MORE_THAN_ONE_ELEMENT
- NO_ELEMENTS
- nameof(predicate)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/c1319af721ff9441.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleAsync.cs:120
var b = false;
try
{
b = _predicate(value);
}
catch (Exception ex)
{
ForwardOnError(ex);
return;
}
if (b)
{
if (_seenValue)
{
try
{
throw new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT);
}
catch (Exception e)
{
ForwardOnError(e);
}
return;
}
_value = value;
_seenValue = true;
}
}
public override void OnCompleted()
{
if (!_seenValue)
{
tryView on GitHub (pinned to 94b5d5ab91)