dotnet/wpf · error · ArgumentException

SR.Animation_DependencyPropertyIsNotAnimatable

Error message

SR.Animation_DependencyPropertyIsNotAnimatable

What it means

Thrown by IAnimatable.ApplyAnimationClock when the target DependencyProperty is not animatable — the property lacks an associated animation (no AnimationStorage / property is not registered as animatable). WPF validates via AnimationStorage.IsPropertyAnimatable before applying the clock.

Solutions

  1. Verify the target property is registered as an animatable DP (defined on an Animatable-derived type with animation support).
  2. Use a property known to be animatable (e.g. UIElement.Opacity, RenderTransform properties) instead.
  3. Check that the dp argument references the correct static DependencyProperty field, not a property name string.

Example fix

// before
button.ApplyAnimationClock(FrameworkElement.TagProperty, clock, HandoffBehavior.SnapshotAndReplace);
// after
button.ApplyAnimationClock(UIElement.OpacityProperty, clock, HandoffBehavior.SnapshotAndReplace);
Defensive patterns

Strategy: validation

Validate before calling

static bool CanAnimate(object target, DependencyProperty dp) =>
    target is System.Windows.Media.Animation.IAnimatable && dp != null;

Type guard

static bool IsAnimatableProperty(DependencyObject o, DependencyProperty dp) => o != null && dp != null && System.Windows.Media.Animation.AnimationStorage.IsPropertyAnimatablePublic(o, dp); // or check dp.OwnerType.IsSubclassOf(typeof(Animatable))

Try / catch

try { target.ApplyAnimationClock(dp, clock, handoff); } catch (ArgumentException ex) when (ex.ParamName == nameof(dp)) { log.Warn($"{dp.Name} on {target.GetType()} is not animatable"); }

Prevention

When it happens

Trigger: Calling ApplyAnimationClock(dp, clock, handoffBehavior) where dp was not registered with an animatable property (e.g. a plain CLR property wrapper or a DP registered without animation support).

Common situations: Animating a non-animatable DP such as a plain double-backed property, or targeting a property on a class that does not derive from Animatable; typos targeting the wrong DependencyProperty field.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/IAnimatableHelper.cs:78

                    /// <param name="clock">
                    /// The AnimationClock that will animate the property. If parameter is null
                    /// then animations will be removed from the property if handoffBehavior is
                    /// SnapshotAndReplace; otherwise the method call will have no result.
                    /// </param>
                    /// <param name="handoffBehavior">
                    /// Determines how the new AnimationClock will transition from or
                    /// affect any current animations on the property.
                    /// </param>
                    public void ApplyAnimationClock(
                        DependencyProperty dp,
                        AnimationClock clock,
                        HandoffBehavior handoffBehavior)
                    {
                        ArgumentNullException.ThrowIfNull(dp);

                        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()));
                        }
                        

View on GitHub (pinned to 81131a70a4)