dotnet/wpf · error · InvalidOperationException

SR.Format(SR.PropertyPathInvalidAccessor, (accessor !=…

Error message

SR.Format(SR.PropertyPathInvalidAccessor, (accessor != null) ? accessor.GetType().FullName : "null")

What it means

PropertyPath.ResolvePropertyName throws this InvalidOperationException when a path parameter at the given index is not a valid property accessor. WPF accepts only PropertyInfo, MethodInfo (getter), or DependencyProperty objects (IsValidAccessor) as accessors in PathParameters, and since an invalid accessor cannot be corrected later during binding evaluation, the path construction fails immediately.

Solutions

  1. Inspect PathParameters[index] and replace the object with a PropertyInfo from Type.GetProperty, a DependencyProperty field, or a MethodInfo for the property getter
  2. If you intended a plain property name, remove the '(n)' indexed-parameter syntax from the path string and use the property name directly
  3. Verify with PropertyPath.IsValidState/IsValidAccessor logic that every entry in PathParameters is one of the three accepted accessor kinds
  4. Use the string-based PropertyPath constructor with a ParserContext so WPF resolves accessors itself instead of supplying them manually

Example fix

// before
var path = new PropertyPath("(0).Name");
path.PathParameters.Add("Name"); // string, not an accessor
// after
var path = new PropertyPath("(0).Name");
path.PathParameters.Add(typeof(Person).GetProperty("Name")); // PropertyInfo accessor
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidPathAccessor(object a) =>
    a == null || a is System.Reflection.PropertyInfo || a is System.Reflection.MethodInfo || a is System.Windows.DependencyProperty;
// check: PathParameters.All(IsValidPathAccessor)

Type guard

bool IsPropertyInfo(object o) => o is System.Reflection.PropertyInfo;

Try / catch

try { var accessor = path.ResolvePropertyName(i, item, ctx, true); }
catch (InvalidOperationException ex) when (ex.Message.Contains("accessor")) { /* replace accessor in PathParameters */ }

Prevention

When it happens

Trigger: Building a PropertyPath whose path string references an indexed parameter '(n)' where PathParameters[n] was populated with an arbitrary object (e.g. a string or custom type) rather than PropertyInfo, MethodInfo, or DependencyProperty; or programmatically inserting a non-accessor object into PathParameters before the path is resolved.

Common situations: Hand-constructing PropertyPath objects with PathParameters instead of passing named properties; passing a reflection MemberInfo of the wrong member kind (e.g. FieldInfo or ConstructorInfo); WPF version changes tightening accessor validation; mistakenly believing any object resolving the property is accepted.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d1a5adb8629ea07b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/PropertyPath.cs:554

            }
        }

        // resolve a single DP name
        private object ResolvePropertyName(string name, object item, Type ownerType, object context, bool throwOnError)
        {
            string propertyName = name;
            int index;

            // first see if the name is an index into the parameter list
            if (IsParameterIndex(name, out index))
            {
                if (0 <= index && index < PathParameters.Count)
                {
                    object accessor = PathParameters[index];
                    // always throw if the accessor isn't valid - this error cannot
                    // be corrected later on.
                    if (!IsValidAccessor(accessor))
                        throw new InvalidOperationException(SR.Format(SR.PropertyPathInvalidAccessor,
                                    (accessor != null) ? accessor.GetType().FullName : "null"));

                    return accessor;
                }
                else if (throwOnError)
                    throw new InvalidOperationException(SR.Format(SR.PathParametersIndexOutOfRange, index, PathParameters.Count));
                else return null;
            }

            // handle attached-property syntax:  (TypeName.PropertyName)
            if (IsPropertyReference(name))
            {
                name = name.Substring(1, name.Length-2);

                int lastIndex = name.LastIndexOf('.');
                if (lastIndex >= 0)
                {
                    // attached property - get the owner type

View on GitHub (pinned to 81131a70a4)