dotnet/reactive · error · InvalidOperationException

Strings_Linq.NO_ELEMENTS

Error message

Strings_Linq.NO_ELEMENTS

What it means

ListObservable's Last property blocks until the source sequence terminates and then throws InvalidOperationException with Strings_Linq.NO_ELEMENTS if no elements were recorded (the list is empty). It is the non-blocking API equivalent of Last() with throw-on-empty semantics.

Solutions

  1. Check Count/recorded results before reading Last and handle the empty case
  2. Subscribe to the OnError notification (OnError property) first, since an errored source never yields a Last value
  3. Catch InvalidOperationException around the property access

Example fix

// before
var last = listObservable.Last; // throws when empty
// after
if (listObservable.Count > 0) { var last = listObservable.Last; } else { /* handle empty */ }
Defensive patterns

Strategy: try-catch

Validate before calling

if (listObservable.Count == 0) { /* handle empty */ } else { var last = listObservable.Last; }

Try / catch

try { var last = listObservable.Last; } catch (InvalidOperationException) { /* no recorded elements */ }

Prevention

When it happens

Trigger: Reading .Last on a ListObservable whose subscribed source completed (or errored) without emitting any OnNext values.

Common situations: Capturing the final value of a UI or test stream that never fired; source errored immediately so only an error notification was recorded, then code still asks for Last.

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/8e250af64f62be9c. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/ListObservable.cs:57

        }

        private void Wait()
        {
            _subject.DefaultIfEmpty().Wait();
        }

        /// <summary>
        /// Returns the last value of the observable sequence.
        /// </summary>
        public T Value
        {
            get
            {
                Wait();

                if (_results.Count == 0)
                {
                    throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
                }

                return _results[_results.Count - 1];
            }
        }
        /// <summary>
        /// Determines the index of a specific item in the ListObservable.
        /// </summary>
        /// <param name="item">The element to determine the index for.</param>
        /// <returns>The index of the specified item in the list; -1 if not found.</returns>
        public int IndexOf(T item)
        {
            Wait();
            return _results.IndexOf(item);
        }

        /// <summary>
        /// Inserts an item to the ListObservable at the specified index.

View on GitHub (pinned to 94b5d5ab91)