PrismLibrary/Prism · error · InvalidOperationException

Tried to subscribe to PropertyChanged in the object that…

Error message

Tried to subscribe to PropertyChanged in the object that defines the '{propObserverNodeRoot.PropertyInfo.Name}' property, but the object does not implement INotifyPropertyChanged.

What it means

The root of the property chain expression must be a constant (a concrete object instance) that implements INotifyPropertyChanged; otherwise change notifications cannot be observed. When the constant root object does not implement INotifyPropertyChanged, PropertyObserver throws this InvalidOperationException.

Solutions

  1. Make the root object's class implement INotifyPropertyChanged
  2. Base the root object on Prism's ObservableObject/BindableBase
  3. Observe the property on a different object that does raise change notifications

Example fix

// before
class Settings { public string Name { get; set; } }
// after
class Settings : BindableBase { private string _name; public string Name { get => _name; set => SetProperty(ref _name, value); } }
Defensive patterns

Strategy: type-guard

Validate before calling

var root = ((ConstantExpression)((LambdaExpression)expr).Body).Value;
bool ok = root is INotifyPropertyChanged;
// only observe roots implementing INotifyPropertyChanged

Type guard

static bool IsObservableRoot<T>(Expression<Func<T>> e) => e.Body is ConstantExpression c && c.Value is INotifyPropertyChanged;

Try / catch

try { PropertyObserver.Create(expr).Subscribe(); }
catch (InvalidOperationException) { /* root lacks INPC — subscribe manually or fix the model */ }

Prevention

When it happens

Trigger: Calling PropertyObserver.Create(() => plainPocoObject.Property) where plainPocoObject is a constant reference but its class lacks INotifyPropertyChanged.

Common situations: Observing properties on plain POCO/model classes, static objects, or DTOs that were never wired for change notification.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/9428547eb50e2484. Report an issue: GitHub.

Appendix: source

Thrown at src/Prism.Core/Commands/PropertyObserver.cs:53

            }

            if (propertyExpression is not ConstantExpression constantExpression)
                throw new NotSupportedException("Operation not supported for the given expression type. " +
                                                "Only MemberExpression and ConstantExpression are currently supported.");

            var propObserverNodeRoot = new PropertyObserverNode(propNameStack.Pop(), _action);
            PropertyObserverNode previousNode = propObserverNodeRoot;
            foreach (var propName in propNameStack) // Create a node chain that corresponds to the property chain.
            {
                var currentNode = new PropertyObserverNode(propName, _action);
                previousNode.Next = currentNode;
                previousNode = currentNode;
            }

            object? propOwnerObject = constantExpression.Value;

            if (propOwnerObject is not INotifyPropertyChanged inpcObject)
                throw new InvalidOperationException("Tried to subscribe to PropertyChanged in the object that " +
                                                    $"defines the '{propObserverNodeRoot.PropertyInfo.Name}' property, but the object does not implement INotifyPropertyChanged.");

            propObserverNodeRoot.SubscribeListenerFor(inpcObject);
        }

        /// <summary>
        /// Observes a property that implements INotifyPropertyChanged, and automatically calls a custom action on 
        /// property changed notifications. The given expression must be in this form: "() => Prop.NestedProp.PropToObserve".
        /// </summary>
        /// <param name="propertyExpression">Expression representing property to be observed. Ex.: "() => Prop.NestedProp.PropToObserve".</param>
        /// <param name="action">Action to be invoked when PropertyChanged event occurs.</param>
        internal static PropertyObserver Observes<T>(Expression<Func<T>> propertyExpression, Action action)
        {
            return new PropertyObserver(propertyExpression.Body, action);
        }
    }
}

View on GitHub (pinned to 358118cd64)