dotnet/wpf · error · InvalidOperationException

Storyboard_TargetPropertyRequired

Storyboard_TargetPropertyRequired

Error message

SR.Format(SR.Storyboard_TargetPropertyRequired, currentTimeline.GetType().ToString())

What it means

ClockTreeWalkRecursive resolved a target object for a timeline but found no property path: Storyboard.TargetProperty was not set. An animation must know which property to animate, so Storyboard.Begin throws an InvalidOperationException identifying the timeline's type.

Solutions

  1. Add Storyboard.TargetProperty="PropertyName" to the timeline (e.g. Opacity or (Canvas.Left)).
  2. In code, call Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")).
  3. Verify the property exists on the target type and use parenthesis syntax for attached/complex paths.

Example fix

// before
var anim = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(anim, "MyPanel");
sb.Children.Add(anim); // no target property

// after
var anim = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(anim, "MyPanel");
Storyboard.SetTargetProperty(anim, new PropertyPath("Opacity"));
sb.Children.Add(anim);
Defensive patterns

Strategy: validation

Validate before calling

if (Storyboard.GetTargetProperty(anim) == null)
    throw new InvalidOperationException("Timeline missing Storyboard.TargetProperty");

Type guard

bool HasTargetProperty(Timeline t) => Storyboard.GetTargetProperty(t) != null;

Try / catch

try { sb.Begin(fe); }
catch (InvalidOperationException ex) when (ex.Message.Contains(nameof(DoubleAnimation))) {
    // fix: add Storyboard.TargetProperty
}

Prevention

When it happens

Trigger: A child animation (DoubleAnimation, ColorAnimation, etc.) lacks Storyboard.TargetProperty when the storyboard is begun, even if a target name/object was provided.

Common situations: Copy-pasting an animation and deleting the TargetProperty line; building animations in code with Storyboard.SetTargetName but forgetting Storyboard.SetTargetProperty; writing TargetProperty as 'Property' by mistake in XAML.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs:453

                    // (Not a Storyboard, as used for "shared clocks" mode.)
                    targetObject = containingObject as FrameworkElement;
                    if(targetObject == null)
                    {
                        targetObject = containingObject as FrameworkContentElement;
                    }

                    if( targetObject == null )
                    {
                        // The containing object is not an FE or FCE.
                        throw new InvalidOperationException(SR.Format(SR.Storyboard_NoTarget, currentTimeline.GetType().ToString() ));
                    }
                }
            }

            // See if we have a property name to use.
            if( currentPropertyPath == null )
            {
                throw new InvalidOperationException(SR.Format(SR.Storyboard_TargetPropertyRequired, currentTimeline.GetType().ToString() ));
            }

            // A property name can be a straightforward property name (like "Angle")
            // but may be a more complex multi-step property path.  The two cases
            // are handled differently.
            using(currentPropertyPath.SetContext(targetObject))
            {
                if( currentPropertyPath.Length < 1 )
                {
                    throw new InvalidOperationException(SR.Storyboard_PropertyPathEmpty);
                }

                VerifyPathIsAnimatable(currentPropertyPath);

                if( currentPropertyPath.Length == 1 )
                {
                    // We have a simple single-step property.
                    targetProperty = currentPropertyPath.GetAccessor(0) as DependencyProperty;

View on GitHub (pinned to 81131a70a4)