dotnet/wpf · error · InvalidOperationException
SR.Format(SR.Storyboard_AnimationMismatch…
Error message
SR.Format(SR.Storyboard_AnimationMismatch, animationClock.Timeline.GetType(), targetProperty.Name, targetProperty.PropertyType)
What it means
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.
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.
Example fix
// before <ColorAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:1" /> <!-- after --> <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:1" />
Defensive patterns
Strategy: validation
Validate before calling
static bool AnimationMatchesProperty(DependencyProperty dp, AnimationClock clock)
{
var animType = clock.Timeline.GetType();
return dp.PropertyType == typeof(double) && animType.Name.StartsWith("Double")
|| dp.PropertyType == typeof(Color) && animType.Name.StartsWith("Color")
|| dp.PropertyType == typeof(Thickness) && animType.Name.StartsWith("Thickness")
|| dp.PropertyType == typeof(Point) && animType.Name.StartsWith("Point");
} Type guard
bool IsMatchingAnimation(DependencyProperty dp, Timeline t) =>
t.GetType().Name.StartsWith(dp.PropertyType.Name) || t is ObjectAnimationUsingKeyFrames; Try / catch
try { storyboard.Begin(target, true); }
catch (InvalidOperationException ex) when (ex.Message.Contains("animation"))
{
// inspect ex.Message for propertyType and swap the child timeline type
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- Animation_AnimationTimelineTypeMismatch
- CannotChangeAfterSealed
- CannotChangeAfterSealed
- SR.Animation_AnimationTimelineTypeMismatch
- SR.Animation_ChildMustBeKeyFrame
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d6f6dca37a9837e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs:796
else if( propertyAccessor is PropertyDescriptor )
{
return ((PropertyDescriptor)propertyAccessor).Name;
}
else
{
return "[Unknown]";
}
}
/// <summary>
/// Makes sure that the given clock can animate the given property -
/// throw an exception otherwise.
/// </summary>
private static void VerifyAnimationIsValid( DependencyProperty targetProperty, AnimationClock animationClock )
{
if( !AnimationStorage.IsAnimationClockValid(targetProperty, animationClock) )
{
throw new InvalidOperationException(SR.Format(SR.Storyboard_AnimationMismatch, animationClock.Timeline.GetType(), targetProperty.Name, targetProperty.PropertyType));
}
}
/// <summary>
/// For complex property paths, we need to dig our way down to the
/// property and attach the animation clock there. We will not be able to
/// actually attach the clocks if the targetProperty points to a frozen
/// Freezable. More extensive handling will be required for that case.
/// </summary>
private void ProcessComplexPath( HybridDictionary clockMappings, DependencyObject targetObject,
PropertyPath path, AnimationClock animationClock, HandoffBehavior handoffBehavior, Int64 layer )
{
Debug.Assert(path.Length > 1, "This method shouldn't even be called for a simple property path.");
// For complex paths, the target object/property differs from the actual
// animated object/property.
//
// Example:View on GitHub (pinned to 81131a70a4)