dotnet/reactive · error · InvalidOperationException

Strings_Linq.NO_ELEMENTS

Error message

Strings_Linq.NO_ELEMENTS

What it means

Observable.Aggregate throws InvalidOperationException with Strings_Linq.NO_ELEMENTS when the source sequence completes without emitting any elements. Without a seed, Aggregate has no accumulation to produce, so OnCompleted forwards an error instead of a result (mirroring LINQ-to-Objects Aggregate behavior).

Solutions

  1. Use the seed overload: Aggregate(source, seed, accumulator) so an empty sequence yields the seed
  2. Handle the error in the observer's OnError or Catch: source.Aggregate(acc).Catch(Observable.Return(seed))
  3. Ensure the source actually emits elements (check upstream filters/conditions)

Example fix

// before
source.Aggregate((acc, x) => acc + x).Subscribe(...); // throws if empty
// after
source.Aggregate(0, (acc, x) => acc + x).Subscribe(...);
Defensive patterns

Strategy: try-catch

Validate before calling

bool hasAny = null; source.Materialize().Where(n => n.Kind == NotificationKind.OnNext).Take(1).Subscribe(...); // probe if emptiness matters

Try / catch

source.Aggregate((acc, x) => acc + x)
    .Catch<TSource>((InvalidOperationException e) => Observable.Return(seed))
    .Subscribe(onNext, onError, onCompleted);

Prevention

When it happens

Trigger: Subscribing to Observable.Aggregate(source, accumulator) (no seed overload) where the source completes empty, e.g. an empty array, a filtered-out stream, or a never-pushed subject that completes.

Common situations: Aggregating query results that returned nothing; Sum-like folds over streams whose filter removed all items; cold sources like empty lists passed to Aggregate without a seed.

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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable/Aggregate.cs:67

                        _accumulation = default;
                        ForwardOnError(exception);
                    }
                }
            }

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

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

    internal sealed class Aggregate<TSource, TAccumulate> : Producer<TAccumulate, Aggregate<TSource, TAccumulate>._>

View on GitHub (pinned to 94b5d5ab91)