dotnet/reactive · error · InvalidOperationException

Strings_Linq.MORE_THAN_ONE_ELEMENT

Error message

Strings_Linq.MORE_THAN_ONE_ELEMENT

What it means

Blocking Single/SingleOrDefault (via SingleOrDefaultInternal) throws InvalidOperationException with Strings_Linq.MORE_THAN_ONE_ELEMENT when the queryable sequence emits two or more elements, since Single demands at most one. This check runs before the empty-sequence check.

Solutions

  1. Deduplicate or take the first element: .Take(1).Single()
  2. Fix the source so it truly emits a single value
  3. Use First()/FirstOrDefault() if multiple elements are acceptable

Example fix

// before
var one = queryable.Single(); // 2+ elements -> throws
// after
var one = queryable.Take(1).Single();
Defensive patterns

Strategy: try-catch

Try / catch

try { var v = queryable.Single(); } catch (InvalidOperationException) { /* 0 or 2+ elements */ }

Prevention

When it happens

Trigger: Calling queryable.Single() or SingleOrDefault() on an IQbservable whose source emits more than one OnNext value.

Common situations: Assuming a lookup by a 'unique' key returns one row but the key is not actually unique; a stream that redundantly re-emits an updated value before completing.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/8dac86cbda6a361c. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/QueryLanguage.Blocking.cs:250

        {
            return SingleOrDefault(Where(source, predicate));
        }

        [return: MaybeNull]
        private static TSource SingleOrDefaultInternal<TSource>(IObservable<TSource> source, bool throwOnEmpty)
        {
            using var consumer = new SingleBlocking<TSource>();

            using (source.Subscribe(consumer))
            {
                consumer.Wait();
            }

            consumer._error?.Throw();

            if (consumer._hasMoreThanOneElement)
            {
                throw new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT);
            }

            if (throwOnEmpty && !consumer._hasValue)
            {
                throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
            }

            return consumer._value;
        }

        #endregion

        #region Wait

        public virtual TSource Wait<TSource>(IObservable<TSource> source)
        {
            return LastOrDefaultInternal(source, true)!;
        }

View on GitHub (pinned to 94b5d5ab91)