{"record":{"id":"fbe20a8cefa397c2","repo":"dotnet/wpf","slug":"sr-ianimatable-cantanimatesealeddo","errorCode":null,"errorMessage":"SR.IAnimatable_CantAnimateSealedDO","messagePattern":"SR\\.IAnimatable_CantAnimateSealedDO","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Visual3D.cs","lineNumber":86,"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":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Visual3D.cs#L68-L104","documentation":"Once a DependencyObject is sealed (immutable, e.g. a frozen Freezable or a sealed template/resource instance), animations can no longer be applied to it. Visual3D.ApplyAnimationClock checks IsSealed and throws InvalidOperationException with IAnimatable_CantAnimateSealedDO. Sealing is a WPF mechanism to make objects thread-safe and immutable; mutation via animation is disallowed.","triggerScenarios":"Calling ApplyAnimationClock on a Visual3D (or its transforms/materials) that has been sealed — commonly after Freeze() was called on an associated Freezable, or the object came from a sealed resource/template instance.","commonSituations":"Animating a frozen Transform3D shared via a StaticResource; objects declared in a ResourceDictionary that WPF sealed; performance-driven Freeze() calls made before animations are attached.","solutions":["Call Clone() (or CloneCurrentValue()) on the frozen/sealed object and apply the animation to the clone.","Declare the target as a mutable instance (x:Shared resources or code-created objects) instead of a frozen shared resource.","Delay any Freeze() call until animations no longer need to be applied to the object."],"exampleFix":"// before\nvar transform = (RotateTransform3D)FindResource(\"spinTransform\");\ntransform.ApplyAnimationClock(...); // sealed/frozen\n// after\nvar transform = ((RotateTransform3D)FindResource(\"spinTransform\")).Clone();\ntransform.ApplyAnimationClock(...);","handlingStrategy":"validation","validationCode":"if (target.IsSealed)\n{\n    target = (Visual3D)((Freezable)target).GetAsFrozen is null ? target : CloneForAnimation(target);\n}\ntarget.ApplyAnimationClock(dp, clock, behavior);","typeGuard":"static bool CanAnimate(Visual3D v) => !v.IsSealed;","tryCatchPattern":"try { visual.ApplyAnimationClock(dp, clock, behavior); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"sealed\")) { var clone = CloneForAnimation(visual); clone.ApplyAnimationClock(dp, clock, behavior); }","preventionTips":["Defer Freeze() on any Freezable/Visual3D until animations are no longer applied.","Never animate objects obtained via StaticResource without cloning first.","Assert !IsSealed in animation setup helpers."],"tags":["wpf","animation","invalid-operation","freezable"],"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-21T21:30:21.729Z"}