{"record":{"id":"d6f6dca37a9837e1","repo":"dotnet/wpf","slug":"sr-format-sr-storyboard-animationmismatch-animationclock","errorCode":null,"errorMessage":"SR.Format(SR.Storyboard_AnimationMismatch, animationClock.Timeline.GetType(), targetProperty.Name, targetProperty.PropertyType)","messagePattern":"SR\\.Format\\(SR\\.Storyboard_AnimationMismatch, animationClock\\.Timeline\\.GetType\\(\\), targetProperty\\.Name, targetProperty\\.PropertyType\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs","lineNumber":796,"sourceCode":"        else if( propertyAccessor is PropertyDescriptor )\n        {\n            return ((PropertyDescriptor)propertyAccessor).Name;\n        }\n        else\n        {\n            return \"[Unknown]\";\n        }\n    }\n\n    /// <summary>\n    ///     Makes sure that the given clock can animate the given property -\n    /// throw an exception otherwise.\n    /// </summary>\n    private static void VerifyAnimationIsValid( DependencyProperty targetProperty, AnimationClock animationClock )\n    {\n        if( !AnimationStorage.IsAnimationClockValid(targetProperty, animationClock) )\n        {\n            throw new InvalidOperationException(SR.Format(SR.Storyboard_AnimationMismatch, animationClock.Timeline.GetType(), targetProperty.Name, targetProperty.PropertyType));\n        }\n    }\n\n    /// <summary>\n    ///     For complex property paths, we need to dig our way down to the\n    /// property and attach the animation clock there.  We will not be able to\n    /// actually attach the clocks if the targetProperty points to a frozen\n    /// Freezable.  More extensive handling will be required for that case.\n    /// </summary>\n    private void ProcessComplexPath( HybridDictionary clockMappings, DependencyObject targetObject,\n        PropertyPath path, AnimationClock animationClock, HandoffBehavior handoffBehavior, Int64 layer )\n    {\n        Debug.Assert(path.Length > 1, \"This method shouldn't even be called for a simple property path.\");\n\n        // For complex paths, the target object/property differs from the actual\n        //  animated object/property.\n        //\n        // Example:","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs#L778-L814","documentation":"The AnimationClock being applied must match the target DependencyProperty's value type — IsAnimationClockValid rejects clocks whose Timeline produces an incompatible type. VerifyAnimationIsValid throws this InvalidOperationException naming the clock's Timeline type, the property, and its expected PropertyType.","triggerScenarios":"Applying a Storyboard whose child AnimationTimeline type does not fit the target property — e.g. a DoubleAnimation targeting a Color property, or a ColorAnimation targeting a double/Thickness property, via Begin, Apply, or HandoffBehavior composition.","commonSituations":"Copy-pasting storyboards between properties of different types; Animatable sub-objects (GradientStop.Color vs element.Opacity) swapped; refactors changing property types; animations from shared resource dictionaries applied to mismatched targets.","solutions":["Use an AnimationTimeline matching the property type: DoubleAnimation for double, ColorAnimation for Color, ThicknessAnimation for Thickness, PointAnimation for Point, etc.","Use ObjectAnimationUsingKeyFrames for non-standard types.","Update the child timeline type inside the storyboard for the named target property.","Check the exception's propertyType field and pick the matching animation class.","Split the storyboard so each property gets a correctly-typed animation."],"exampleFix":"// before\n<ColorAnimation Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:1\" />\n<!-- after -->\n<DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:1\" />","handlingStrategy":"validation","validationCode":"static bool AnimationMatchesProperty(DependencyProperty dp, AnimationClock clock)\n{\n    var animType = clock.Timeline.GetType();\n    return dp.PropertyType == typeof(double) && animType.Name.StartsWith(\"Double\")\n        || dp.PropertyType == typeof(Color) && animType.Name.StartsWith(\"Color\")\n        || dp.PropertyType == typeof(Thickness) && animType.Name.StartsWith(\"Thickness\")\n        || dp.PropertyType == typeof(Point) && animType.Name.StartsWith(\"Point\");\n}","typeGuard":"bool IsMatchingAnimation(DependencyProperty dp, Timeline t) =>\n    t.GetType().Name.StartsWith(dp.PropertyType.Name) || t is ObjectAnimationUsingKeyFrames;","tryCatchPattern":"try { storyboard.Begin(target, true); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"animation\"))\n{\n    // inspect ex.Message for propertyType and swap the child timeline type\n}","preventionTips":["Match AnimationTimeline type to the DP's PropertyType every time","Use ObjectAnimationUsingKeyFrames for unusual types","Review storyboard XAML when reusing across different properties","Add unit tests asserting each timeline type against its target property type"],"tags":["wpf","animation","type-mismatch","storyboard"],"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"}