{"record":{"id":"48b7266830d24c7f","repo":"dotnet/wpf","slug":"sr-defaultattachablepropertystorecannotaddinstance","errorCode":null,"errorMessage":"SR.DefaultAttachablePropertyStoreCannotAddInstance","messagePattern":"SR\\.DefaultAttachablePropertyStoreCannotAddInstance","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/AttachablePropertyServices.cs","lineNumber":198,"sourceCode":"                Dictionary<AttachableMemberIdentifier, object> instanceProperties;\n                if (!instanceStorage.Value.TryGetValue(instance, out instanceProperties))\n                {\n                    instanceProperties = new Dictionary<AttachableMemberIdentifier, object>();\n                    //\n                    // Workaround lack of TryAdd for ConditionalWeakTable\n                    try\n                    {\n                        instanceStorage.Value.Add(instance, instanceProperties);\n                    }\n                    catch (ArgumentException)\n                    {\n                        //\n                        // If Add fails we raced and the item should exist\n                        if (!instanceStorage.Value.TryGetValue(instanceStorage, out instanceProperties))\n                        {\n                            //\n                            // If for some reason it doesn't, throw.\n                            throw new InvalidOperationException(SR.DefaultAttachablePropertyStoreCannotAddInstance);\n                        }\n                    }\n                }\n\n                lock (instanceProperties)\n                {\n                    instanceProperties[name] = value;\n                }\n            }\n\n            // <summary>\n            // Retrieve the value of the attached property 'name'. If there is not attached property then return false.\n            // </summary>\n            public bool TryGetProperty<T>(object instance, AttachableMemberIdentifier name, out T value)\n            {\n                if (instanceStorage.IsValueCreated)\n                {\n                    Dictionary<AttachableMemberIdentifier, object> instanceProperties;","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/AttachablePropertyServices.cs#L180-L216","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Avoid calling SetProperty concurrently for the same target instance; serialize access with a lock around the instance.","Retry the SetProperty call — the race is transient and a second attempt should find or add the entry.","Update to a newer .NET/WPF servicing release where the store race handling may be improved.","If reproducible single-threaded, file a bug: this indicates an internal invariant violation."],"exampleFix":"// before\nParallel.For(0, 100, i => AttachablePropertyServices.SetProperty(target, keyExpr, value));\n// after\nprivate static readonly object _targetLock = new object();\nlock (_targetLock)\n{\n    AttachablePropertyServices.SetProperty(target, keyExpr, value);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    AttachablePropertyServices.SetProperty(target, keyExpr, value);\n}\ncatch (InvalidOperationException) when (ex.Message.Contains(\"attachable property store\") /* SR.DefaultAttachablePropertyStoreCannotAddInstance */)\n{\n    // transient race: retry once on the same thread\n    AttachablePropertyServices.SetProperty(target, keyExpr, value);\n}","preventionTips":["Do not call AttachablePropertyServices.SetProperty on the same instance from multiple threads concurrently.","Route attachable-property mutations through a single owning thread or a per-instance lock.","Keep .NET/WPF runtime updated; the race handling lives in the framework, not your code."],"tags":["wpf","xaml","race-condition","threading","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}