{"record":{"id":"f50421668f8b0840","repo":"dotnet/reactive","slug":"expected-qbservable-toqueryable","errorCode":null,"errorMessage":"Expected Qbservable.ToQueryable.","messagePattern":"Expected Qbservable\\.ToQueryable\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/ObservableQuery.cs","lineNumber":53,"sourceCode":"\n        IQueryable<TElement> IQueryProvider.CreateQuery<TElement>(Expression expression)\n        {\n            //\n            // Here we're on the edge between IQbservable and IQueryable for the local\n            // execution case. E.g.:\n            //\n            //   observable.AsQbservable().<operators>.ToQueryable()\n            //\n            // This should be turned into a local execution, with the push-to-pull\n            // adapter in the middle, so we rewrite to:\n            //\n            //   observable.AsQbservable().<operators>.ToEnumerable().AsQueryable()\n            //\n            if (expression is not MethodCallExpression call ||\n                call.Method.DeclaringType != typeof(Qbservable) ||\n                call.Method.Name != nameof(Qbservable.ToQueryable))\n            {\n                throw new ArgumentException(Strings_Providers.EXPECTED_TOQUERYABLE_METHODCALL, nameof(expression));\n            }\n\n            //\n            // This is the IQbservable<T> object corresponding to the lhs. Now wrap\n            // it in two calls to get the local queryable.\n            //\n            var arg0 = call.Arguments[0];\n            var res =\n                Expression.Call(\n                    AsQueryable.MakeGenericMethod(typeof(TElement)),\n                    Expression.Call(\n                        typeof(Observable).GetMethod(nameof(Observable.ToEnumerable))!.MakeGenericMethod(typeof(TElement)),\n                        arg0\n                    )\n                );\n\n            //\n            // Queryable operator calls should be taken care of by the provider for","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/ObservableQuery.cs#L35-L71","documentation":"CreateQuery on the IQbservable<T>->IQueryable bridge provider only accepts expression trees whose single method call is Qbservable.ToQueryable. Any other expression shape or method is rejected with ArgumentException because the provider cannot translate it back to an IQbservable pipeline. This is a guard for an internal conversion pattern (observable.AsQbservable().<operators>.ToEnumerable().AsQueryable()).","triggerScenarios":"Calling IQueryProvider.CreateQuery with an expression that is not a MethodCallExpression, whose declaring type is not Qbservable, or whose method name is not ToQueryable — e.g. composing Queryable operators directly on the queryable without going through AsQbservable().","commonSituations":"Developers manually building expression trees against an ExpressionViewModel/IQueryable view of an IQbservable, or using LINQ query syntax over the wrapped queryable with operators the bridge does not recognize.","solutions":["Only call CreateQuery with the result of an AsQbservable().ToQueryable() expression tree; use observable.AsQbservable() and operators on IQbservable directly instead of Queryable operators","Check the expression before passing: it must be a MethodCallExpression with Method.DeclaringType == typeof(Qbservable) and Method.Name == nameof(Qbservable.ToQueryable)","Perform filtering/transformation on the IQbservable<T> side before converting to IQueryable"],"exampleFix":"// before\nIQueryable<int> q = provider.CreateQuery(Expression.Call(typeof(Queryable), \"Where\", new[]{typeof(int)}, source.Expression, predicate));\n// after\nIQueryable<int> q = source.AsQbservable().Where(x => x > 0).ToEnumerable().AsQueryable();","handlingStrategy":"validation","validationCode":"if (expr is not MethodCallExpression mc || mc.Method.DeclaringType != typeof(Qbservable) || mc.Method.Name != nameof(Qbservable.ToQueryable)) throw new ArgumentException(\"Only Qbservable.ToQueryable expressions are supported\", nameof(expr));","typeGuard":"static bool IsToQueryableCall(Expression e) => e is MethodCallExpression c && c.Method.DeclaringType == typeof(Qbservable) && c.Method.Name == nameof(Qbservable.ToQueryable);","tryCatchPattern":null,"preventionTips":["Build the queryable only via observable.AsQbservable().ToQueryable(), never hand-constructed expression trees","Apply operators on the IQbservable<T>, not the IQueryable view","Assert the expression shape in unit tests before calling CreateQuery"],"tags":["linq","expression-tree","rx","argument-exception"],"backgroundTag":"invalid-argument-value","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}