dotnet/wpf · error · ArgumentException

SR.Animation_AnimationTimelineTypeMismatch

Error message

SR.Animation_AnimationTimelineTypeMismatch

What it means

Visual3D.ApplyAnimationClock validates that the AnimationClock's Timeline matches the property type of the DependencyObject property being animated (AnimationStorage.IsAnimationValid). If the timeline's target value type is not compatible with dp.PropertyType (e.g. a DoubleAnimation clock applied to a Point3DAnimation-compatible property), an ArgumentException is thrown naming the clock parameter. WPF requires the clock's timeline type to be the one registered for that animatable property.

Solutions

  1. Create the clock from a timeline whose value type matches dp.PropertyType (e.g. use Point3DAnimation/QuaternionRotation3D-family timelines for 3D properties).
  2. Check the DP's property type via dp.PropertyType and its PropertyMetadata to confirm which AnimationTimeline type it expects before creating the clock.
  3. Use BeginAnimation with a correctly typed AnimationTimeline instead of manually constructing clocks, so type matching is enforced at the timeline level.

Example fix

// before
clock = (rotationAnim).CreateClock(); // rotationAnim is DoubleAnimation
visual.ApplyAnimationClock(RotateTransform3D.RotationProperty, clock);
// after
var rotationAnim = new Rotation3DAnimation(new AxisAngleRotation3D(axis, 90), Duration.FromSeconds(1));
visual.ApplyAnimationClock(RotateTransform3D.RotationProperty, rotationAnim.CreateClock());
Defensive patterns

Strategy: validation

Validate before calling

if (clock != null && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))
{
    throw new InvalidOperationException($"Clock timeline {clock.Timeline.GetType().Name} is incompatible with {dp.Name} ({dp.PropertyType}).");
}
visual.ApplyAnimationClock(dp, clock, handoffBehavior);

Type guard

static bool IsClockCompatible(DependencyProperty dp, AnimationClock clock) =>
    clock?.Timeline != null && dp.PropertyType.IsInstanceOfType(((AnimationTimeline)clock.Timeline).GetCurrentValue(null, clock));

Try / catch

try { visual.ApplyAnimationClock(dp, clock, behavior); }
catch (ArgumentException ex) when (ex.ParamName == "clock") { /* rebuild clock from a timeline matching dp.PropertyType */ }

Prevention

When it happens

Trigger: Calling visual3D.ApplyAnimationClock(dp, clock, handoffBehavior) where clock is non-null and AnimationStorage.IsAnimationValid(dp, clock.Timeline) returns false — i.e. clock.Timeline.GetType() does not produce values assignable to dp.PropertyType.

Common situations: Applying a clock created from a DoubleAnimation to a property typed Point3D or Vector3D; reusing a clock built for one property (e.g. Opacity) on a 3D transform property; refactoring code that changed the DP type but kept the old clock.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Visual3D.cs:76

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

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

        /// <summary>
        /// Starts an animation for a DependencyProperty. The animation will
        /// begin when the next frame is rendered.

View on GitHub (pinned to 81131a70a4)