dotnet/wpf · error · InvalidOperationException

SR.DefaultAttachablePropertyStoreCannotAddInstance

Error message

SR.DefaultAttachablePropertyStoreCannotAddInstance

What it means

AttachablePropertyServices.SetProperty stores per-instance property dictionaries in a ConditionalWeakTable. After TryGetValue fails (the instance entry did not exist) the code inserts one; if that Add also fails it means a race with another thread that should have made the entry visible, but it did not — an unexpected internal state, so InvalidOperationException with SR.DefaultAttachablePropertyStoreCannotAddInstance is thrown.

Solutions

  1. Avoid calling SetProperty concurrently for the same target instance; serialize access with a lock around the instance.
  2. Retry the SetProperty call — the race is transient and a second attempt should find or add the entry.
  3. Update to a newer .NET/WPF servicing release where the store race handling may be improved.
  4. If reproducible single-threaded, file a bug: this indicates an internal invariant violation.

Example fix

// before
Parallel.For(0, 100, i => AttachablePropertyServices.SetProperty(target, keyExpr, value));
// after
private static readonly object _targetLock = new object();
lock (_targetLock)
{
    AttachablePropertyServices.SetProperty(target, keyExpr, value);
}
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    AttachablePropertyServices.SetProperty(target, keyExpr, value);
}
catch (InvalidOperationException) when (ex.Message.Contains("attachable property store") /* SR.DefaultAttachablePropertyStoreCannotAddInstance */)
{
    // transient race: retry once on the same thread
    AttachablePropertyServices.SetProperty(target, keyExpr, value);
}

Prevention

When it happens

Trigger: Calling AttachablePropertyServices.SetProperty(instance, key, value) concurrently from multiple threads on the same instance such that the internal ConditionalWeakTable add races and fails, or (theoretically) an internal store invariant being violated.

Common situations: Multi-threaded WPF/XAML code attaching properties to the same object instance from worker threads; high-contention scenarios hitting the race window in the default attachable property store.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/AttachablePropertyServices.cs:198

                Dictionary<AttachableMemberIdentifier, object> instanceProperties;
                if (!instanceStorage.Value.TryGetValue(instance, out instanceProperties))
                {
                    instanceProperties = new Dictionary<AttachableMemberIdentifier, object>();
                    //
                    // Workaround lack of TryAdd for ConditionalWeakTable
                    try
                    {
                        instanceStorage.Value.Add(instance, instanceProperties);
                    }
                    catch (ArgumentException)
                    {
                        //
                        // If Add fails we raced and the item should exist
                        if (!instanceStorage.Value.TryGetValue(instanceStorage, out instanceProperties))
                        {
                            //
                            // If for some reason it doesn't, throw.
                            throw new InvalidOperationException(SR.DefaultAttachablePropertyStoreCannotAddInstance);
                        }
                    }
                }

                lock (instanceProperties)
                {
                    instanceProperties[name] = value;
                }
            }

            // <summary>
            // Retrieve the value of the attached property 'name'. If there is not attached property then return false.
            // </summary>
            public bool TryGetProperty<T>(object instance, AttachableMemberIdentifier name, out T value)
            {
                if (instanceStorage.IsValueCreated)
                {
                    Dictionary<AttachableMemberIdentifier, object> instanceProperties;

View on GitHub (pinned to 81131a70a4)