dotnet/wpf · error · InvalidOperationException

Storyboard_NoTarget

Storyboard_NoTarget

Error message

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

What it means

ClockTreeWalkRecursive found a timeline with no resolvable target: no Storyboard.TargetName, no Storyboard.Target, and the containing object is not a FrameworkElement/FrameworkContentElement, so no target object can be derived. Storyboard.Begin throws an InvalidOperationException naming the timeline type.

Solutions

  1. Add Storyboard.TargetName="elementName" to each timeline (or the parent Storyboard so children inherit).
  2. Or set Storyboard.Target to the actual target DependencyObject in code via Storyboard.SetTarget.
  3. Call Begin on a proper FrameworkElement (window/control) that serves as namescope and containing object.

Example fix

// before
var sb = (Storyboard)FindResource("fadeSb");
sb.Begin(this); // children lack TargetName/Target

// after
Storyboard.SetTargetName(sb, "MyPanel"); // or per-child SetTargetName
sb.Begin(this);
Defensive patterns

Strategy: validation

Validate before calling

if (Storyboard.GetTargetName(anim) == null && Storyboard.GetTarget(anim) == null)
    throw new InvalidOperationException("Timeline has no TargetName/Target");

Type guard

bool HasTarget(Timeline t) => Storyboard.GetTargetName(t) != null || Storyboard.GetTarget(t) != null;

Try / catch

try { sb.Begin(fe); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no target") || ex.Message.Contains(nameof(DoubleAnimation))) {
    // fix: assign Storyboard.TargetName/Target
}

Prevention

When it happens

Trigger: Calling Storyboard.Begin where a child animation lacks both Storyboard.TargetName and Storyboard.Target and there is no implicit containing FE/FCE — e.g. sb.Begin on a non-FE object, or resource-defined storyboards begun without a namescope argument.

Common situations: Calling sb.Begin(this) where 'this' is not an FE/FCE; forgetting TargetName on the first animation of a resource-defined storyboard; moving a storyboard from a trigger (which supplied an implicit target) to code-behind without adding TargetName.

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/9d2ba8e368ceb7f9. Report an issue: GitHub.

Appendix: source

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

                {
                    DependencyObject mentor = Helper.FindMentor(containingObject);

                    targetObject = ResolveTargetName(currentObjectName, nameScope, mentor);
                }
                else
                {
                    // The containing object must be either an FE or FCE.
                    // (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);

View on GitHub (pinned to 81131a70a4)