{"record":{"id":"dc3f9bef227aa5ea","repo":"dotnet/maui","slug":"cannot-attach-effect-to-multiple-sources","errorCode":null,"errorMessage":"Cannot attach Effect to multiple sources","messagePattern":"Cannot attach Effect to multiple sources","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/Element/Element.cs","lineNumber":895,"sourceCode":"\t\t\t{\n\t\t\t\tIReadOnlyList<Element> children = queue.Dequeue().LogicalChildrenInternal;\n\t\t\t\tfor (var i = 0; i < children.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tvar child = children[i] as VisualElement;\n\t\t\t\t\tif (child == null || !child.IsVisible)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tyield return child;\n\t\t\t\t\tqueue.Enqueue(child);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid AttachEffect(Effect effect)\n\t\t{\n\t\t\tif (_effectControlProvider == null)\n\t\t\t\treturn;\n\t\t\tif (effect.IsAttached)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot attach Effect to multiple sources\");\n\n\t\t\tEffect effectToRegister = effect;\n\t\t\tif (effect is RoutingEffect re && re.Inner != null)\n\t\t\t\teffectToRegister = re.Inner;\n\n\t\t\t_effectControlProvider.RegisterEffect(effectToRegister);\n\t\t\teffectToRegister.Element = this;\n\t\t\teffect.SendAttached();\n\t\t}\n\n\t\tvoid EffectsOnClearing(object sender, EventArgs eventArgs)\n\t\t{\n\t\t\tforeach (Effect effect in _effects)\n\t\t\t{\n\t\t\t\teffect?.ClearEffect();\n\t\t\t}\n\t\t}\n","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/Element/Element.cs#L877-L913","documentation":"Thrown by Element.AttachEffect when the Effect being attached already has IsAttached == true. An Effect is a single-instance object tied to one element; once attached and its SendAttached called, attempting to attach it to a second element is illegal. This protects against sharing one Effect instance across multiple controls.","triggerScenarios":"Adding the same Effect instance to more than one Element's Effects collection; reusing a single Effect object in multiple elements' Effects lists; adding an already-attached effect during a Replace collection-changed notification.","commonSituations":"Creating one Effect instance and adding it to multiple controls' Effects collections (a common mistake when factoring effects into shared fields); defining a RoutingEffect once and sharing it across a page's elements; effects loaded from a shared resource dictionary referenced by multiple views.","solutions":["Create a new Effect instance for each element — instantiate effects per-control rather than sharing.","If sharing a RoutingEffect, verify re.Inner is null or also clone it.","In a Replace notification, ensure the old effect is cleared (ClearEffect) before the new one is attached."],"exampleFix":"// before\nvar effect = new MyRoutingEffect(); // shared\nview1.Effects.Add(effect);\nview2.Effects.Add(effect); // throws: already attached\n// after\nview1.Effects.Add(new MyRoutingEffect());\nview2.Effects.Add(new MyRoutingEffect());","handlingStrategy":"validation","validationCode":"foreach (var target in targets)\n{\n    if (effect.IsAttached)\n        effect = CloneEffect(effect); // create a fresh instance\n    target.Effects.Add(effect);\n}","typeGuard":"static bool IsEffectFree(Effect e) => !e.IsAttached;","tryCatchPattern":"try { element.Effects.Add(effect); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Cannot attach Effect to multiple sources\")\n{\n    element.Effects.Add(CloneEffect(effect)); // attach a fresh instance\n}","preventionTips":["Never share a single Effect instance across multiple elements.","Create effects per-element (factory or new instance each time).","When reusing effects from a resource dictionary, clone before attaching."],"tags":["maui","effects","invalidoperation","sharing","instance-reuse"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}