{"record":{"id":"7a1f740e8fb033fc","repo":"PrismLibrary/Prism","slug":"tried-to-subscribe-to-propertychanged-in-the-object-that-7a1f74","errorCode":null,"errorMessage":"Tried to subscribe to PropertyChanged in the object that defines the '{Next?.PropertyInfo.Name}' property, but the object does not implement INotifyPropertyChanged.","messagePattern":"Tried to subscribe to PropertyChanged in the object that defines the '(.+?)' property, but the object does not implement INotifyPropertyChanged\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Prism.Core/Commands/PropertyObserverNode.cs","lineNumber":45,"sourceCode":"                Next.UnsubscribeListener();\n                GenerateNextNode();\n            };\n        }\n\n        public void SubscribeListenerFor(INotifyPropertyChanged inpcObject)\n        {\n            _inpcObject = inpcObject;\n            _inpcObject.PropertyChanged += OnPropertyChanged;\n\n            if (Next != null) GenerateNextNode();\n        }\n\n        private void GenerateNextNode()\n        {\n            var nextProperty = PropertyInfo.GetValue(_inpcObject);\n            if (nextProperty == null) return;\n            if (nextProperty is not INotifyPropertyChanged nextInpcObject)\n                throw new InvalidOperationException(\"Tried to subscribe to PropertyChanged in the object that \" +\n                                                    $\"defines the '{Next?.PropertyInfo.Name}' property, but the object does not implement INotifyPropertyChanged.\");\n\n            Next?.SubscribeListenerFor(nextInpcObject);\n        }\n\n        private void UnsubscribeListener()\n        {\n            if (_inpcObject != null)\n                _inpcObject.PropertyChanged -= OnPropertyChanged;\n\n            Next?.UnsubscribeListener();\n        }\n\n        private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)\n        {\n            if (e?.PropertyName == PropertyInfo.Name || string.IsNullOrEmpty(e?.PropertyName))\n            {\n                _action?.Invoke();","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Prism.Core/Commands/PropertyObserverNode.cs#L27-L63","documentation":"When a middle node in the property chain resolves its property value to advance the chain, that intermediate value must implement INotifyPropertyChanged for the observer to keep listening. If the intermediate object is a plain object, this InvalidOperationException is thrown.","triggerScenarios":"Observing a chain like () => vm.PlainChild.SubProperty where vm.PlainChild returns an object that does not implement INotifyPropertyChanged and is not null.","commonSituations":"Nested view-models where an inner child class was forgotten to be made observable; refactors that replaced an observable child with a POCO.","solutions":["Make the intermediate child class implement INotifyPropertyChanged","Derive the intermediate class from BindableBase/ObservableObject","Restructure the observed chain to stop at observable objects"],"exampleFix":"// before\nclass Child { public string Name { get; set; } }\n// after\nclass Child : BindableBase { private string _name; public string Name { get => _name; set => SetProperty(ref _name, value); } }","handlingStrategy":"validation","validationCode":"var mid = vm.PlainChild;\nbool ok = mid == null || mid is INotifyPropertyChanged;\n// only build chains whose intermediate objects are observable","typeGuard":"static bool ChainIsObservable(object root, params string[] path) { /* walk path checking each value is null or INotifyPropertyChanged */ return true; }","tryCatchPattern":"try { PropertyObserver.Create(() => vm.Child.Sub).Subscribe(); }\ncatch (InvalidOperationException) { /* intermediate child lacks INPC */ }","preventionTips":["Ensure every object in a multi-level chain implements INotifyPropertyChanged","Base nested child models on BindableBase","Keep observed chains shallow and fully observable"],"tags":["prism","propertyobserver","inotifypropertychanged","property-chain"],"backgroundTag":"missing-dependency","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}