{"record":{"id":"8dba297e340853fe","repo":"dotnet/wpf","slug":"sr-ianimatable-cantanimatesealeddo-ianimatablehelper","errorCode":null,"errorMessage":"SR.IAnimatable_CantAnimateSealedDO","messagePattern":"SR\\.IAnimatable_CantAnimateSealedDO","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/IAnimatableHelper.cs","lineNumber":94,"sourceCode":"                        if (!AnimationStorage.IsPropertyAnimatable(this, dp))\n                        {\n                            throw new ArgumentException(SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType()), nameof(dp));\n                        }\n\n                        if (clock != null\n                            && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))\n                        {\n                            throw new ArgumentException(SR.Format(SR.Animation_AnimationTimelineTypeMismatch, clock.Timeline.GetType(), dp.Name, dp.PropertyType), nameof(clock));\n                        }\n\n                        if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))\n                        {\n                            throw new ArgumentException(SR.Animation_UnrecognizedHandoffBehavior);\n                        }\n\n                        if (IsSealed)\n                        {\n                            throw new InvalidOperationException(SR.Format(SR.IAnimatable_CantAnimateSealedDO, dp, this.GetType()));\n                        }\n                        \n                        AnimationStorage.ApplyAnimationClock(this, dp, clock, handoffBehavior);\n                    }\n\n                    /// <summary>\n                    /// Starts an animation for a DependencyProperty. The animation will\n                    /// begin when the next frame is rendered.\n                    /// </summary>\n                    /// <param name=\"dp\">\n                    /// The DependencyProperty to animate.\n                    /// </param>\n                    /// <param name=\"animation\">\n                    /// <para>The AnimationTimeline to used to animate the property.</para>\n                    /// <para>If the AnimationTimeline's BeginTime is null, any current animations\n                    /// will be removed and the current value of the property will be held.</para>\n                    /// <para>If this value is null, all animations will be removed from the property\n                    /// and the property value will revert back to its base value.</para>","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/IAnimatableHelper.cs#L76-L112","documentation":"Thrown by IAnimatable.ApplyAnimationClock when the target object IsSealed. Sealed (frozen/immutable) Freezable/DependencyObject instances cannot be modified, including having animation clocks applied.","triggerScenarios":"Calling ApplyAnimationClock on a frozen Freezable (e.g. a frozen Brush) or a sealed DependencyObject.","commonSituations":"Animating a Brush that was frozen via Freeze() for performance; sharing a frozen resource across elements and trying to animate it; animations targeting styles/resources marked frozen.","solutions":["Call Clone() or CloneCurrentValue() on the frozen object and animate the unfrozen clone.","Ensure the source object is not frozen before animating (check Freezable.IsFrozen).","Animate a different unfrozen instance, e.g. animate the element property instead of the shared frozen resource."],"exampleFix":"// before\nfrozenBrush.ApplyAnimationClock(SolidColorBrush.ColorProperty, clock);\n// after\nvar animatableBrush = frozenBrush.Clone();\nanimatableBrush.ApplyAnimationClock(SolidColorBrush.ColorProperty, clock);","handlingStrategy":"type-guard","validationCode":"if (target is Freezable f && f.IsFrozen) target = f.Clone();","typeGuard":"static bool IsMutableForAnimation(DependencyObject o) => o is not Freezable f || !f.IsFrozen;","tryCatchPattern":"try { target.ApplyAnimationClock(dp, clock, handoff); } catch (InvalidOperationException ex) when (target is Freezable fz && fz.IsFrozen) { target = fz.Clone(); target.ApplyAnimationClock(dp, clock, handoff); }","preventionTips":["Check Freezable.IsFrozen before mutating or animating any Freezable.","Keep separate frozen (shared, read-only) and unfrozen (animatable) instances.","Delay Freeze() until after all animation setup is complete."],"tags":["wpf","animation","freezable","immutability"],"backgroundTag":"invalid-state-transition","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"}