{"record":{"id":"3cf4da1f683d9434","repo":"dotnet/wpf","slug":"sr-sharingnonsharableexpression","errorCode":null,"errorMessage":"SR.SharingNonSharableExpression","messagePattern":"SR\\.SharingNonSharableExpression","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyObject.cs","lineNumber":666,"sourceCode":"\n            // First try to validate the value; only after this validation fails should we\n            // do the more expensive checks (type checks) for the less common scenarios\n            if (!newValueHasExpressionMarker)\n            {\n                bool isValidValue = isInternal ? dp.IsValidValueInternal(value) : dp.IsValidValue(value);\n\n                // for properties of type \"object\", we have to always check for expression & deferredreference\n                if (!isValidValue || dp.IsObjectType)\n                {\n                    // 2nd most common is expression\n                    newExpr = value as Expression;\n                    if (newExpr != null)\n                    {\n                        // For Expressions, perform additional validation\n                        // Make sure Expression is \"attachable\"\n                        if (!newExpr.Attachable)\n                        {\n                            throw new ArgumentException(SR.SharingNonSharableExpression);\n                        }\n\n                        // Check dispatchers of all Sources\n                        // CALLBACK\n                        newSources = newExpr.GetSources();\n                        ValidateSources(this, newSources, newExpr);\n                    }\n                    else\n                    {\n                        // and least common is DeferredReference\n                        isDeferredReference = (value is DeferredReference);\n                        if (!isDeferredReference)\n                        {\n                            if (!isValidValue)\n                            {\n                                // it's not a valid value & it's not an expression, so throw\n                                throw new ArgumentException(SR.Format(SR.InvalidPropertyValue, value, dp.Name));\n                            }","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyObject.cs#L648-L684","documentation":"During SetValueCommon, if the new value is an Expression (binding/expression markup extension) that is not Attachable (i.e. its Attachable property is false), WPF throws ArgumentException(SR.SharingNonSharableExpression). Expressions must be attachable to be shared/assigned onto dependency properties; non-attachable expressions cannot be shared across DependencyObjects or attached in the current context.","triggerScenarios":"Assigning an expression instance (BindingBase, custom Expression) with Attachable == false to a DP via SetValue; reusing a single expression object across multiple targets when it was created non-shareable (e.g. a Binding whose-source state forbids sharing).","commonSituations":"Caching one Binding object and applying it to many controls; programmatically building expressions with incorrect internal flags; expressions deserialized from XAML that lost attachable state.","solutions":["Create a fresh Binding/Expression instance per target instead of sharing one instance.","Use BindingOperations.SetBinding with a properly constructed Binding whose properties allow attachment.","If writing a custom Expression/MarkupExtension, implement and set Attachable correctly (allow multiple attach or clone on attach)."],"exampleFix":"// before\nvar binding = new Binding(\"Name\") { Source = vm };\ncontrol1.SetBinding(TextBlock.TextProperty, binding);\ncontrol2.SetBinding(TextBlock.TextProperty, binding); // shared\n// after\ncontrol1.SetBinding(TextBlock.TextProperty, new Binding(\"Name\") { Source = vm });\ncontrol2.SetBinding(TextBlock.TextProperty, new Binding(\"Name\") { Source = vm });","handlingStrategy":"type-guard","validationCode":"if (value is Expression expr && !expr.Attachable)\n    throw new InvalidOperationException(\"Expression is not attachable; create a new instance per target.\");","typeGuard":"bool IsShareableExpression(object v) => v is not Expression e || e.Attachable;","tryCatchPattern":"try { target.SetValue(TargetProperty, exprValue); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"attachable\") || ex.Message.Contains(\"Expression\"))\n{\n    target.SetBinding(TargetProperty, CreateFreshBinding()); // new instance per target\n}","preventionTips":["Create one Binding/Expression instance per target; never share across DependencyObjects.","Use BindingOperations.SetBinding rather than raw SetValue for bindings.","When authoring custom expressions, implement Attachable (or clone on attach)."],"tags":["wpf","binding","expression","argument"],"backgroundTag":"incompatible-source-type","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}