Skip to content

[Bug]: OAPH throws InvalidOperationException in generic viewmodel #184

Open

Description

@conormcg94

Describe the bug 🐞

I'm migrating to V26 but running into an issue with generic viewmodels that inherit from ReactiveObject. The ToProperty() extension can't be called in a generic class and ToPropertyUnsafe() throws InvalidOperationException at runtime.

Problematic Code:

public partial class ViewModel2<T> : ReactiveObject
{
    public string Name => _nameHelper.Value;
    private readonly ObservableAsPropertyHelper<string> _nameHelper;

    public ViewModel2()
    {
        var signal = new BehaviorSignal<string>("");
        _nameHelper = signal.AsObservable().ToPropertyUnsafe(this, x => x.Name);
    }
}

Step to reproduce

I've created a simple project to show the issue Tests 0 and 1 work but Test 2 throws the exception

using ReactiveUI;
using ReactiveUI.Primitives;
using ReactiveUI.Primitives.Signals;
using ReactiveUI.SourceGenerators;

namespace RxTest;

public partial class ViewModel0 : ReactiveObject
{
    [ObservableAsProperty]
    public partial string Name { get; }

    public ViewModel0()
    {
        var signal = new BehaviorSignal<string>("");
        _nameHelper = signal.AsObservable().ToProperty(this, x => x.Name);
    }
}

public partial class ViewModel1 : ReactiveObject
{
    public string Name => _nameHelper.Value;
    private readonly ObservableAsPropertyHelper<string> _nameHelper;

    public ViewModel1()
    {
        var signal = new BehaviorSignal<string>("");
        _nameHelper = signal.AsObservable().ToProperty(this, x => x.Name);
    }
}

public partial class ViewModel2<T> : ReactiveObject
{
    public string Name => _nameHelper.Value;
    private readonly ObservableAsPropertyHelper<string> _nameHelper;

    public ViewModel2()
    {
        var signal = new BehaviorSignal<string>("");
        _nameHelper = signal.AsObservable().ToPropertyUnsafe(this, x => x.Name);
    }
}

public class UnitTest1
{
    [Fact]
    public void Test0()
    {
        var vm = new ViewModel0();
    }

    [Fact]
    public void Test1()
    {
        var vm = new ViewModel1();
    }

    [Fact]
    public void Test2()
    {
        var vm = new ViewModel2<string>();
    }
}

Stacktrace:

System.InvalidOperationException
RxTest.ViewModel2`1[[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] raises no change notification ToPropertyUnsafe can reach. Implement ReactiveUI's IReactiveObject, declare a RaisePropertyChanged or OnPropertyChanged method, or declare a field-like PropertyChanged event.
   at ReactiveUI.Binding.Fallback.RuntimePropertyRaiser.Create(Object owner, String propertyName) in /_/src/ReactiveUI.Binding.Shared/Fallback/RuntimePropertyRaiser.cs:line 110
   at ReactiveUI.Binding.ReactiveUIBindingExtensions.CreateUnsafeRaiser[TObj](TObj source, String propertyName) in /_/src/ReactiveUI.Binding.Shared/Mixins/ReactiveUIBindingExtensions.ToProperty.Unsafe.cs:line 1077
   at ReactiveUI.Binding.ReactiveUIBindingExtensions.CreateUnsafeHelper[TObj,TRet](IObservable`1 target, TObj source, String propertyName, TRet initialValue, Boolean deferSubscription, ISequencer scheduler) in /_/src/ReactiveUI.Binding.Shared/Mixins/ReactiveUIBindingExtensions.ToProperty.Unsafe.cs:line 1019
   at RxTest.ViewModel2`1..ctor() in C:\Users\Conor\Source\repos\RxTest\RxTest\UnitTest1.cs:line 40
   at RxTest.UnitTest1.Test2() in C:\Users\Conor\Source\repos\RxTest\RxTest\UnitTest1.cs:line 61
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Reproduction repository

https://github.com/reactiveui/ReactiveUI

Expected behavior

Test 2 should function them same as Test 0 and Test 1

Screenshots 🖼️

No response

IDE

No response

Operating system

No response

Version

No response

Device

No response

ReactiveUI Version

26.0.1

Additional information ℹ️

No response

Activity

  1. reyntjesr commented on Oct 16, 2026

    @reyntjesr

    I got the same error with generic viewmodels.

    When I added the following property to the viewmodel the error disappeared:

        public void RaisePropertyChanged(string propertyName) => IReactiveObjectExtensions.RaisePropertyChanged(this, propertyName);
    
  2. conormcg94 commented on Oct 16, 2026

    @conormcg94
    Author

    Thank you, that works for me as well. I thought inheriting from ReactiveObject was enough

  3. glennawatson commented on Oct 18, 2026

    @glennawatson
    Contributor

    Thanks all, I'll add that to the class. Moved to binding, debatable which one it belongs in since there will be fixes required in both repos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions