dotnet/reactive · error · InvalidOperationException

Strings_Linq.NO_ELEMENTS

Error message

Strings_Linq.NO_ELEMENTS

What it means

Blocking First/FirstOrDefault (via FirstOrDefaultInternal) drains the queryable sequence and throws InvalidOperationException with Strings_Linq.NO_ELEMENTS when the sequence completed without emitting any value and a default is not allowed (throwOnEmpty). It represents 'no elements' rather than an error in the underlying stream.

Solutions

  1. Use FirstOrDefault() to receive default(T) instead of throwing when the sequence may be empty
  2. Check whether the source sequence is expected to be non-empty and fix the producer
  3. Catch InvalidOperationException around the blocking call and treat it as an empty-result condition

Example fix

// before
var first = queryable.First(); // throws on empty
// after
var first = queryable.FirstOrDefault(); // default(T) when empty
Defensive patterns

Strategy: try-catch

Validate before calling

// cannot know emptiness before subscribing; prefer the non-throwing API instead

Try / catch

try { var v = queryable.First(); } catch (InvalidOperationException) { /* sequence was empty */ var v = default(T); }

Prevention

When it happens

Trigger: Calling queryable.First() or FirstOrDefault(source => predicate, throwOnEmpty semantics) on an empty IQbservable, or where the OnError path stored an exception that was rethrown and the sequence produced no value.

Common situations: Waiting for the first result of a remote queryable stream that produced no data (empty DB table, filter matched nothing); race where the source completed before subscription processed a value.

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


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

Appendix: source

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

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

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

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

            consumer._error?.Throw();

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

            return consumer._value;
        }

        #endregion

        #region + ForEach +

        public virtual void ForEach<TSource>(IObservable<TSource> source, Action<TSource> onNext)
        {
            using var sink = new ForEach<TSource>.Observer(onNext);

            using (source.SubscribeSafe(sink))
            {
                sink.Wait();
            }

View on GitHub (pinned to 94b5d5ab91)