dotnet/reactive · error · ArgumentException
Invalid expression tree type.
Error message
Invalid expression tree type.
What it means
ObservableQueryProvider.CreateQuery<TResult> verifies that the expression tree's static Type is assignable to IObservable<TResult> and throws ArgumentException (INVALID_TREE_TYPE, message 'Invalid expression tree type.') otherwise. Qbservable providers can only execute queries rooted in an observable sequence.
Solutions
- Build the query from an expression rooted at an IQbservable/IObservable<TResult> matching the requested TResult
- Fix the generic type parameter so TResult matches the observable element type of the expression
- If porting LINQ-to-Objects code, rewrite the query against the Qbservable provider's AsQbservable entry point instead of passing IQueryable expressions
Example fix
// before Expression expr = Expression.Constant(list); // System.Collections.Generic.List<int> var q = provider.CreateQuery<int>(expr); // after Expression expr = Expression.Constant(observableInts); // IObservable<int> var q = provider.CreateQuery<int>(expr);
Defensive patterns
Strategy: validation
Validate before calling
if (expression != null && !typeof(IObservable<TResult>).IsAssignableFrom(expression.Type)) throw new InvalidOperationException("expression tree must be rooted in IObservable<T>"); Try / catch
try { provider.CreateQuery<T>(expression); } catch (ArgumentException ex) { /* rebuild tree with correct IObservable<T> root */ } Prevention
- Keep IQbservable and IQueryable pipelines separate
- Verify expression.Type matches the requested TResult before CreateQuery
When it happens
Trigger: Calling CreateQuery<TResult>(expression) (ObservableQuery.cs:24) with an expression whose Type is not IObservable<TResult> — e.g. an expression representing IQueryable, a raw value, or a different generic result type than requested.
Common situations: Mixing IQueryable and IQbservable trees (passing an EF/IQueryable expression into a Qbservable provider); calling CreateQuery<int> on a tree typed IObservable<long>; hand-built expression trees with the wrong Type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/ff22f5cc94941723.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/ObservableQuery.cs:30
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()
//
// This should be turned into a local execution, with the push-to-pull
// adapter in the middle, so we rewrite to:
//
// observable.AsQbservable().<operators>.ToEnumerable().AsQueryable()
//View on GitHub (pinned to 94b5d5ab91)