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
- Call storyboard.Begin(containingObject, isControllable: true) before any control operation and keep the same Storyboard instance.
- Track applied storyboards (e.g. in a field) and pass the same instance and containing object to Pause/Resume/Seek.
- Guard control calls: only invoke them if you know Begin succeeded (set a flag after Begin).
- 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
- Always Begin with isControllable: true if you will Pause/Resume/Seek
- Keep one Storyboard instance per animated host, stored in a field
- Apply and control with the exact same containing object
- Check for a successful Begin before issuing control operations
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
- CannotChangeAfterSealed
- CannotChangeAfterSealed
- SR.Format(SR.BindingExpressionStatusChanged, _status…
- SR.Format(SR.CannotCallRunMultipleTimes…
- SR.Format(SR.Storyboard_AnimationMismatch…
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)