dotnet/reactive · error · InvalidOperationException

Strings_Linq.NO_ELEMENTS

Error message

Strings_Linq.NO_ELEMENTS

What it means

LastAsync without a predicate throws InvalidOperationException with Strings_Linq.NO_ELEMENTS when the source completes without emitting any value, since there is no last element. Thrown in OnCompleted when _seenValue is false and forwarded via OnError.

Solutions

  1. Use LastOrDefaultAsync which emits default(T) instead of erroring on an empty source
  2. Catch InvalidOperationException in OnError and use a fallback
  3. Ensure the source emits at least one value before completion

Example fix

// before
source.LastAsync().Subscribe(x => ...);
// after
source.LastOrDefaultAsync().Subscribe(x => Console.WriteLine(x));
Defensive patterns

Strategy: try-catch

Try / catch

source.LastAsync().Subscribe(
    x => Console.WriteLine(x),
    ex => { if (ex is InvalidOperationException) Console.WriteLine(default); else throw ex; });

Prevention

When it happens

Trigger: Subscribing to source.LastAsync() where the source completes with zero OnNext calls.

Common situations: Taking the latest reading from a sensor stream that produced nothing; last event of a session that was filtered empty.

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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable/LastAsync.cs:51

                public override void OnNext(TSource value)
                {
                    _value = value;
                    _seenValue = true;
                }

                public override void OnError(Exception error)
                {
                    _value = default;
                    ForwardOnError(error);
                }

                public override void OnCompleted()
                {
                    if (!_seenValue)
                    {
                        try
                        {
                            throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
                        }
                        catch (Exception e)
                        {
                            ForwardOnError(e);
                        }
                    }
                    else
                    {
                        var value = _value!;
                        _value = default;
                        ForwardOnNext(value);
                        ForwardOnCompleted();
                    }
                }
            }
        }

        internal sealed class Predicate : Producer<TSource, Predicate._>

View on GitHub (pinned to 94b5d5ab91)