dotnet/wpf · error · XamlObjectReaderException

SR.ObjectReaderAttachedPropertyNotFound

Error message

SR.ObjectReaderAttachedPropertyNotFound

What it means

XamlObjectReader throws this when the object graph carries an attached-property record whose member cannot be resolved on the owning type: owningType.GetAttachableMember(memberName) returns null. The reader cannot map the recorded attached property name back to a real XamlMember.

Solutions

  1. Restore/keep the attached property's Get/Set accessor pair on the owning type with the original name
  2. Update the recorded member name to the current attached-property name
  3. Remove the stale attached-property entry from the object graph before reading
  4. Re-register the attached property with DependencyProperty.RegisterAttached/ReadProperty so GetAttachableMember can find it

Example fix

// before: member removed after upgrade
// after: restore accessors
public static double GetTilt(UIElement o) => (double)o.GetValue(TiltProperty);
public static void SetTilt(UIElement o, double v) => o.SetValue(TiltProperty, v);
Defensive patterns

Strategy: validation

Validate before calling

foreach (var (owner, memberName) in attachedProps)
    if (owner.GetAttachableMember == null /* via XamlType in your context: */ )
        ; // resolve via schemaContext.GetXamlType(owner.GetType()).GetAttachableMember(memberName)
var xm = schemaContext.GetXamlType(ownerType)?.GetAttachableMember(memberName);
if (xm == null) throw new InvalidOperationException($"Unknown attached property {ownerType}.{memberName}");

Try / catch

try { using var r = new XamlObjectReader(obj); ... } catch (XamlObjectReaderException ex) when (ex.Message.Contains("AttachedPropertyNotFound")) { /* prune or remap stale attached props */ }

Prevention

When it happens

Trigger: new XamlObjectReader(obj) where a serialized attached-property key (ap.Key.MemberName) names a member that does not exist (or is not an attachable member) on the owning type — typically after the defining class was renamed/removed or the name was recorded incorrectly.

Common situations: Referenced library upgraded and an attached property (e.g. custom Canvas-style attached property) renamed or deleted; custom attached properties registered via different names between write and read; typos in custom attached-property registration.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlObjectReader.cs:1885

            private static void AddAttachedProperties(object value, ObjectMarkupInfo objectInfo, SerializerContext context)
            {
                var props = context.Runtime.GetAttachedProperties(value);
                if (props is not null)
                {
                    foreach (var ap in props)
                    {
                        XamlType owningType = context.GetXamlType(ap.Key.DeclaringType);
                        if (!owningType.IsVisibleTo(context.LocalAssembly))
                        {
                            continue;
                        }

                        XamlMember attachedProperty = owningType.GetAttachableMember(ap.Key.MemberName);

                        if (attachedProperty is null)
                        {
                            throw new XamlObjectReaderException(SR.Format(SR.ObjectReaderAttachedPropertyNotFound, owningType, ap.Key.MemberName));
                        }

                        if (!CanPropertyXamlRoundtrip(attachedProperty, context))
                        {
                            continue;
                        }

                        var propertyInfo = MemberMarkupInfo.ForAttachedProperty(value, attachedProperty, ap.Value, context);
                        if (propertyInfo is not null)
                        {
                            objectInfo.Properties.Add(propertyInfo);
                        }
                    }
                }
            }

            private static ObjectMarkupInfo ForNull()
            {

View on GitHub (pinned to 81131a70a4)