{"record":{"id":"c15b74c7352ebc45","repo":"dotnet/wpf","slug":"sr-animation-animationtimelinetypemismatch","errorCode":null,"errorMessage":"SR.Animation_AnimationTimelineTypeMismatch","messagePattern":"SR\\.Animation_AnimationTimelineTypeMismatch","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Visual3D.cs","lineNumber":76,"sourceCode":"        /// Determines how the new AnimationClock will transition from or\n        /// affect any current animations on the property.\n        /// </param>\n        public void ApplyAnimationClock(\n            DependencyProperty dp,\n            AnimationClock clock,\n            HandoffBehavior handoffBehavior)\n        {\n            ArgumentNullException.ThrowIfNull(dp);\n\n            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.","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Visual3D.cs#L58-L94","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclock = (rotationAnim).CreateClock(); // rotationAnim is DoubleAnimation\nvisual.ApplyAnimationClock(RotateTransform3D.RotationProperty, clock);\n// after\nvar rotationAnim = new Rotation3DAnimation(new AxisAngleRotation3D(axis, 90), Duration.FromSeconds(1));\nvisual.ApplyAnimationClock(RotateTransform3D.RotationProperty, rotationAnim.CreateClock());","handlingStrategy":"validation","validationCode":"if (clock != null && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))\n{\n    throw new InvalidOperationException($\"Clock timeline {clock.Timeline.GetType().Name} is incompatible with {dp.Name} ({dp.PropertyType}).\");\n}\nvisual.ApplyAnimationClock(dp, clock, handoffBehavior);","typeGuard":"static bool IsClockCompatible(DependencyProperty dp, AnimationClock clock) =>\n    clock?.Timeline != null && dp.PropertyType.IsInstanceOfType(((AnimationTimeline)clock.Timeline).GetCurrentValue(null, clock));","tryCatchPattern":"try { visual.ApplyAnimationClock(dp, clock, behavior); }\ncatch (ArgumentException ex) when (ex.ParamName == \"clock\") { /* rebuild clock from a timeline matching dp.PropertyType */ }","preventionTips":["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."],"tags":["wpf","animation","argument-exception","type-safety"],"backgroundTag":"type-mismatch","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"}