dotnet/wpf · error · InvalidOperationException

SR.Format(SR.IAnimatable_CantAnimateSealedDO, dp…

Error message

SR.Format(SR.IAnimatable_CantAnimateSealedDO, dp, this.GetType())

What it means

Thrown by ContentElement.ApplyAnimationClock when the element IsSealed — i.e. the DependencyObject is sealed (typically because it belongs to a frozen or template-sealed state) and can no longer be animated. WPF throws InvalidOperationException with SR.IAnimatable_CantAnimateSealedDO naming the property and element type.

Solutions

  1. Check element.IsSealed before animating; skip or clone the element if sealed.
  2. Obtain a mutable copy (e.g. CloneCurrentValue or a new instance) instead of animating the sealed instance.
  3. Move animation code earlier in the element lifecycle, before sealing occurs (e.g. before the template is applied).
  4. Animate an ancestor or a wrapper element instead of the sealed object.

Example fix

// before
contentEl.ApplyAnimationClock(dp, clock, HandoffBehavior.Compose);
// after
if (!contentEl.IsSealed)
    contentEl.ApplyAnimationClock(dp, clock, HandoffBehavior.Compose);
Defensive patterns

Strategy: validation

Validate before calling

if (element.IsSealed)
    throw new InvalidOperationException($"Cannot animate sealed element {element.GetType().Name}");

Type guard

bool CanAnimate(ContentElement e) => e != null && !e.IsSealed;

Try / catch

try { el.ApplyAnimationClock(dp, clock, behavior); }
catch (InvalidOperationException ex) when (el.IsSealed) { log.Warn($"Element {el.GetType().Name} is sealed; skipping animation"); }

Prevention

When it happens

Trigger: Calling ApplyAnimationClock on a ContentElement whose IsSealed is true, e.g. an element already sealed by the framework (sealed styles/templates or frozen object state) — checked right before AnimationStorage.ApplyAnimationClock.

Common situations: Attempting to animate elements inside a sealed template or after the object was sealed; animating shared/frozen resources; applying animations during shutdown or after the element was locked by its container.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/21bc94f1ce9a9009. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/ContentElement.cs:87

            if (!AnimationStorage.IsPropertyAnimatable(this, dp))
            {
                throw new ArgumentException(SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType()), nameof(dp));
            }

            if (clock != null
                && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))
            {
                throw new ArgumentException(SR.Format(SR.Animation_AnimationTimelineTypeMismatch, clock.Timeline.GetType(), dp.Name, dp.PropertyType), nameof(clock));
            }

            if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))
            {
                throw new ArgumentException(SR.Animation_UnrecognizedHandoffBehavior);
            }

            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Format(SR.IAnimatable_CantAnimateSealedDO, dp, this.GetType()));
            }

            AnimationStorage.ApplyAnimationClock(this, dp, clock, handoffBehavior);
        }

        /// <summary>
        /// Starts an animation for a DependencyProperty. The animation will
        /// begin when the next frame is rendered.
        /// </summary>
        /// <param name="dp">
        /// The DependencyProperty to animate.
        /// </param>
        /// <param name="animation">
        /// <para>The AnimationTimeline to used to animate the property.</para>
        /// <para>If the AnimationTimeline's BeginTime is null, any current animations
        /// will be removed and the current value of the property will be held.</para>
        /// <para>If this value is null, all animations will be removed from the property
        /// and the property value will revert back to its base value.</para>

View on GitHub (pinned to 81131a70a4)