dotnet/wpf · error · InvalidOperationException
Storyboard_MediaElementRequired
Storyboard_MediaElementRequired
Error message
SR.Storyboard_MediaElementRequired
What it means
Storyboard.Apply or a running MediaTimeline needs somewhere to attach the resulting MediaClock. When the storyboard targets a MediaTimeline, the resolved target (or the storyboard's ContainingObject) must be a MediaElement; ApplyMediaClock throws this InvalidOperationException when both come back null.
Solutions
- Set Storyboard.TargetName/Storyboard.Target to an actual MediaElement in the storyboard's children (the MediaTimeline).
- Ensure the MediaElement is the direct target, not a wrapping control; give the MediaElement its own x:Name and target that.
- If applying manually, pass a MediaElement as the containingObject argument to Storyboard.Apply.
- Register the target name via storyboard.RegisterName so TargetName resolution succeeds.
- Replace the timeline with a non-media animation if the target was never meant to be a media element.
Example fix
// before <Storyboard> <MediaTimeline Source="a.wmv" Storyboard.TargetName="mediaBorder" /> </Storyboard> <!-- after --> <Storyboard> <MediaTimeline Source="a.wmv" Storyboard.TargetName="mediaElement" /> </Storyboard>
Defensive patterns
Strategy: validation
Validate before calling
static bool IsMediaStoryboardTarget(Storyboard sb, FrameworkElement container, string targetName)
{
var target = targetName != null ? container.FindName(targetName) : container;
return target is MediaElement;
} Type guard
static bool IsMediaElement(object o) => o is MediaElement media && media.Clock != null || o is MediaElement;
Try / catch
try { storyboard.Begin(containingObject); }
catch (InvalidOperationException ex) when (ex.Message.Contains("MediaElement"))
{
// fall back: log, retarget to MediaElement, or disable media playback
} Prevention
- Always target MediaTimelines at a named MediaElement
- Never wrap the media target in a layout container when referencing it by name
- Register names used by storyboards via RegisterName
- Unit-test storyboard targets resolve to MediaElement before Begin
When it happens
Trigger: Calling Storyboard.Apply or Begin on a storyboard whose children are MediaTimelines while TargetName/Target resolves to a non-MediaElement (or nothing), and the storyboard has no MediaElement ContainingObject.
Common situations: Targeting a MediaTimeline at an Image or Canvas by mistake; wrapping media in a ContentControl/Viewbox so the target is a container instead of the MediaElement; forgetting to set Storyboard.TargetName so the containing-object fallback is also not a MediaElement.
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
- CannotChangeAfterSealed
- CannotChangeAfterSealed
- SR.Format(SR.Storyboard_AnimationMismatch…
- SR.Format(SR.Storyboard_ComplexPathNotSupported…
- SR.Format(SR.Storyboard_PropertyPathUnresolved, path.Path)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/910596a0066d86b7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs:556
targetMediaElement = ResolveTargetName(currentObjectName, nameScope, mentor ) as MediaElement;
if( targetMediaElement == null )
{
throw new InvalidOperationException(SR.Format(SR.Storyboard_MediaElementNotFound, currentObjectName ));
}
}
else if( currentObject != null )
{
targetMediaElement = currentObject as MediaElement;
}
else
{
targetMediaElement = containingObject as MediaElement;
}
if( targetMediaElement == null )
{
throw new InvalidOperationException(SR.Storyboard_MediaElementRequired);
}
targetMediaElement.Clock = mediaClock;
}
/// <summary>
/// Given an animation clock, add it to the data structure which tracks
/// all the clocks along with their associated target object and property.
/// </summary>
private static void UpdateMappings(
HybridDictionary clockMappings,
ObjectPropertyPair mappingKey,
AnimationClock animationClock)
{
object mappedObject = clockMappings[mappingKey];
Debug.Assert( mappedObject == null || mappedObject is AnimationClock || mappedObject is List<AnimationClock>,View on GitHub (pinned to 81131a70a4)