{"record":{"id":"316bf9074bfaedbc","repo":"PrismLibrary/Prism","slug":"propertyinfo","errorCode":null,"errorMessage":"propertyInfo","messagePattern":"propertyInfo","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Prism.Core/Commands/PropertyObserverNode.cs","lineNumber":22,"sourceCode":"\n#nullable enable\nnamespace Prism.Commands\n{\n    /// <summary>\n    /// Represents each node of nested properties expression and takes care of \n    /// subscribing/unsubscribing INotifyPropertyChanged.PropertyChanged listeners on it.\n    /// </summary>\n    internal class PropertyObserverNode\n    {\n        private readonly Action _action;\n        private INotifyPropertyChanged? _inpcObject;\n\n        public PropertyInfo PropertyInfo { get; }\n        public PropertyObserverNode? Next { get; set; }\n\n        public PropertyObserverNode(PropertyInfo propertyInfo, Action action)\n        {\n            PropertyInfo = propertyInfo ?? throw new ArgumentNullException(nameof(propertyInfo));\n            _action = () =>\n            {\n                action?.Invoke();\n                if (Next == null) return;\n                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()","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Prism.Core/Commands/PropertyObserverNode.cs#L4-L40","documentation":"PropertyObserverNode's constructor requires a PropertyInfo describing the node in the property chain and an Action callback; passing a null PropertyInfo throws ArgumentNullException. The node cannot resolve or subscribe to anything without the property metadata.","triggerScenarios":"Constructing PropertyObserverNode directly (or via reflection/tooling) with a null PropertyInfo argument.","commonSituations":"Custom observers or test code building node chains manually pass null because the expression member was not a PropertyInfo (e.g. a FieldInfo or null member from a malformed expression).","solutions":["Pass a valid PropertyInfo obtained from expression.Member with a type check","Guard the expression member is PropertyInfo before constructing the node"],"exampleFix":"// before\nvar node = new PropertyObserverNode(null, callback);\n// after\nif (expression.Member is PropertyInfo pi)\n    var node = new PropertyObserverNode(pi, callback);","handlingStrategy":"type-guard","validationCode":"bool ok = member is PropertyInfo pi && pi != null;\n// construct PropertyObserverNode only with a resolved PropertyInfo","typeGuard":"static bool TryGetNode(Expression e, out PropertyInfo pi) { pi = (e as MemberExpression)?.Member as PropertyInfo; return pi != null; }","tryCatchPattern":"try { var node = new PropertyObserverNode(pi, action); }\ncatch (ArgumentNullException) { /* pi was null — expression member was not a property */ }","preventionTips":["Resolve PropertyInfo from expression.Member before building nodes","Never pass null PropertyInfo; fail fast with a clear message","Validate member type is PropertyInfo, not FieldInfo or MethodInfo"],"tags":["prism","argumentnull","propertyobserver"],"backgroundTag":"null-argument","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"}