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
- Create the clock from a timeline whose value type matches dp.PropertyType (e.g. use Point3DAnimation/QuaternionRotation3D-family timelines for 3D properties).
- Check the DP's property type via dp.PropertyType and its PropertyMetadata to confirm which AnimationTimeline type it expects before creating the clock.
- 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
- Derive clocks only from timelines whose GetCurrentValue return type equals dp.PropertyType.
- Centralize clock creation in a helper that takes the DP and picks the timeline type.
- Write a unit test per animated DP asserting IsAnimationValid before runtime use.
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
- SR.Animation_UnrecognizedHandoffBehavior
- SR.Animation_UnrecognizedHandoffBehavior
- SR.Format(SR.Animation_AnimationTimelineTypeMismatch…
- SR.Format(SR.Animation_AnimationTimelineTypeMismatch…
- SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable…
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)