dotnet/reactive · error · ArgumentNullException

expression

Error message

expression

What it means

ObservableQueryProvider.CreateQuery<TResult> builds an IQbservable<TResult> from an expression tree and rejects a null expression with ArgumentNullException. The provider needs a valid expression tree to represent the query being composed.

Solutions

  1. Pass a valid Expression (e.g. Expression.Constant(observable) typed as IObservable<TResult>) to CreateQuery
  2. Fix the upstream query-builder so it always constructs an expression before calling CreateQuery
  3. Null-check the expression in your composition layer before invoking the provider

Example fix

// before
Expression expr = builder.TryBuild(); // may be null
var q = provider.CreateQuery<int>(expr);
// after
var expr = builder.TryBuild() ?? Expression.Constant(Observable.Empty<int>());
var q = provider.CreateQuery<int>(expr);
Defensive patterns

Strategy: validation

Validate before calling

if (expression == null) throw new InvalidOperationException("query expression not built");

Try / catch

try { provider.CreateQuery<T>(expression); } catch (ArgumentNullException ex) when (ex.ParamName == "expression") { /* rebuild the expression tree */ }

Prevention

When it happens

Trigger: Calling provider.CreateQuery<TResult>(null) (ObservableQuery.cs:24) — typically via IQbservableProvider/IQueryProvider plumbing when a null expression is passed down, e.g. from custom LINQ-style query composition code.

Common situations: Writing a custom query provider or expression visitor over IQbservable that forwards a null expression; mock/stub query providers returning expressions that are null; dynamic query building that skips expression construction.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/ObservableQuery.cs:25

using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Joins;
using System.Reactive.Linq;
using System.Reflection;

namespace System.Reactive
{
#if HAS_TRIMMABILITY_ATTRIBUTES
    [RequiresUnreferencedCode(Constants_Core.AsQueryableTrimIncompatibilityMessage)]
#endif
    internal class ObservableQueryProvider : IQbservableProvider, IQueryProvider
    {
        public IQbservable<TResult> CreateQuery<TResult>(Expression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            if (!typeof(IObservable<TResult>).IsAssignableFrom(expression.Type))
            {
                throw new ArgumentException(Strings_Providers.INVALID_TREE_TYPE, nameof(expression));
            }

            return new ObservableQuery<TResult>(expression);
        }

        IQueryable<TElement> IQueryProvider.CreateQuery<TElement>(Expression expression)
        {
            //
            // Here we're on the edge between IQbservable and IQueryable for the local
            // execution case. E.g.:
            //
            //   observable.AsQbservable().<operators>.ToQueryable()
            //

View on GitHub (pinned to 94b5d5ab91)