dotnet/wpf · error · InvalidOperationException

SR.Storyboard_NeverApplied

Error message

SR.Storyboard_NeverApplied

What it means

Thrown when a control API (e.g. Pause/Resume/Remove/Seek-style operations that need the storyboard's applied state) finds the storyboard's weak reference missing from the containing object's internal dictionary, meaning the storyboard was never applied to that object. Control operations require a previously applied (Begin'ed) storyboard; one that was only instantiated has no clock to control.

Solutions

  1. Call storyboard.Begin(containingObject, isControllable: true) before any control operation and keep the same Storyboard instance.
  2. Track applied storyboards (e.g. in a field) and pass the same instance and containing object to Pause/Resume/Seek.
  3. Guard control calls: only invoke them if you know Begin succeeded (set a flag after Begin).
  4. If using BeginStoryboard in XAML, name it and control through its ControllableStoryboardAction rather than constructing a separate Storyboard.

Example fix

// before
var sb = new Storyboard(...);
sb.Pause(this); // never applied
// after
var sb = new Storyboard(...);
sb.Begin(this, isControllable: true);
// ... later
sb.Pause(this);
Defensive patterns

Strategy: try-catch

Validate before calling

bool applied = storyboardField != null && storyboardApplied; // set storyboardApplied = true right after Begin(this, isControllable: true)

Type guard

bool IsApplied(Storyboard sb, FrameworkElement host) => sb != null && storyboardApplied && ReferenceEquals(host, storyboardHost);

Try / catch

try { sb.Pause(this); }
catch (InvalidOperationException ex) when (ex.Message.Contains("never been applied")) { sb.Begin(this, isControllable: true); }

Prevention

When it happens

Trigger: Calling storyboard.Pause/Resume/Seek/Remove/SkipToFill (or the IControllableStorybard-related helpers) on a Storyboard that was never Begin'ed against the target, or Begin'ed against a different containing object.

Common situations: Pausing an animation whose Begin call was skipped due to an earlier exception; using a new Storyboard instance each frame and keeping only the newest reference; applying to one Window but controlling against another.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    {
        Clock clock = null;
        WeakReference clockReference = null;

        HybridDictionary clocks = StoryboardClockTreesField.GetValue(o);

        if (clocks != null)
        {
            clockReference = clocks[this] as WeakReference;
        }

        if (clockReference == null)
        {
            if (throwIfNull)
            {
                // This exception indicates that the storyboard has never been applied.
                // We check the weak reference because the only way it can be null
                // is if it had never been put in the dictionary.
                throw new InvalidOperationException(SR.Storyboard_NeverApplied);
            }
            else  if (TraceAnimation.IsEnabledOverride )
            {
                TraceAnimation.Trace(
                    TraceEventType.Warning,
                    TraceAnimation.StoryboardNotApplied,
                    operation,
                    this,
                    o);
            }
        }



        if (clockReference != null)
        {
            clock = clockReference.Target as Clock;

View on GitHub (pinned to 81131a70a4)