dotnet/wpf · error · InvalidOperationException
Storyboard_TargetNameNotAllowedInStyle
Storyboard_TargetNameNotAllowedInStyle
Error message
SR.Format(SR.Storyboard_TargetNameNotAllowedInStyle, nameString)
What it means
During ClockTreeWalkRecursive (invoked from Storyboard.Begin), a timeline has a TargetName while the current namescope is a Style. Styles forbid targeting other objects — animations inside a Style may only affect the styled (implicit target) object — so any TargetName is rejected with an InvalidOperationException.
Solutions
- Remove TargetName (and Target) from the timeline in the Style; the animation implicitly targets the styled element — specify only Storyboard.TargetProperty.
- Move the storyboard to Window/UserControl resources and trigger it via EventTrigger with SourceName if cross-element targeting is required.
- Use a ControlTemplate trigger with TargetName if targeting named template parts (allowed in templates, not styles).
Example fix
<!-- before: throws -->
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="otherPanel" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<!-- after: implicit target only -->
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1"/> Defensive patterns
Strategy: validation
Validate before calling
// In a Style, fail fast if a timeline declares TargetName
if (inStyle && timeline.GetValue(Storyboard.TargetNameProperty) != null)
throw new InvalidOperationException("Storyboard.TargetName is not allowed inside a Style"); Try / catch
try { BeginStoryboard(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Style")) {
// remove TargetName or move the storyboard out of the Style
} Prevention
- Omit TargetName/Target inside Styles — the styled element is the implicit target.
- Use ControlTemplate triggers with TargetName for template parts, not Styles.
- Keep cross-element storyboards in Window/UserControl resources.
When it happens
Trigger: Defining a Storyboard inside a <Style> (Setters/Triggers/EnterActions/ExitActions) where a child timeline sets Storyboard.TargetName="someElement", then beginning the storyboard via trigger actions.
Common situations: Trying to animate another control from a Style trigger; porting a storyboard from Window resources into a Style without removing TargetName; misunderstanding that Style animations implicitly target the styled element.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Storyboard_NameNotFound
- SR.Format(SR.CannotHavePropertyInStyle…
- SR.Format(SR.CannotHavePropertyInTemplate…
- SR.Format(SR.CannotHavePropertyInTemplate…
- SR.Format(SR.NameNotFound, propertyValue.ChildName)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/c7171f556277ffc3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/Storyboard.cs:397
Int64 layer /* Remains the same through all the recursive calls */)
{
Timeline currentTimeline = currentClock.Timeline;
DependencyObject targetObject = parentObject;
string currentObjectName = parentObjectName;
PropertyPath currentPropertyPath = parentPropertyPath;
// If we have target object/property information, use it instead of the
// parent's information.
string nameString = (string)currentTimeline.GetValue(TargetNameProperty);
if( nameString != null )
{
if( nameScope is Style )
{
// We are inside a Style - we don't let people target anything.
// They're only allowed to modify the Styled object, which is
// already the implicit target.
throw new InvalidOperationException(SR.Format(SR.Storyboard_TargetNameNotAllowedInStyle, nameString));
}
currentObjectName = nameString;
}
// The TargetProperty trumps the TargetName property.
DependencyObject localTargetObject = (DependencyObject) currentTimeline.GetValue(TargetProperty);
if( localTargetObject != null )
{
targetObject = localTargetObject;
currentObjectName = null;
}
PropertyPath propertyPath = (PropertyPath)currentTimeline.GetValue(TargetPropertyProperty);
if( propertyPath != null )
{
currentPropertyPath = propertyPath;
}
View on GitHub (pinned to 81131a70a4)