dotnet/wpf · error · InvalidOperationException

Storyboard_PropertyPathMustPointToDependencyProperty

Storyboard_PropertyPathMustPointToDependencyProperty

Error message

SR.Format(SR.Storyboard_PropertyPathMustPointToDependencyProperty, currentPropertyPath.Path)

What it means

The first segment of the timeline's PropertyPath did not resolve to a DependencyProperty: PropertyPath.GetAccessor(0) returned something else (e.g. PropertyInfo/MethodInfo). WPF storyboards can only animate dependency properties, so ClockTreeWalkRecursive throws an InvalidOperationException including the offending path string.

Solutions

  1. Point TargetProperty at a real DependencyProperty, e.g. Storyboard.TargetProperty="Opacity" or "(Canvas.Left)".
  2. Use correct parenthesis syntax for attached/complex paths: "(Panel.Background).(SolidColorBrush.Color)".
  3. If the property is not a DP, animate an equivalent DP or make the class a DependencyObject with a DependencyProperty.

Example fix

<!-- before: plain CLR property -->
<DoubleAnimation Storyboard.TargetName="shape" Storyboard.TargetProperty="AngleDegrees" .../>

<!-- after: DependencyProperty path -->
<DoubleAnimation Storyboard.TargetName="shape" Storyboard.TargetProperty="(RotateTransform.Angle)" .../>
Defensive patterns

Strategy: type-guard

Validate before calling

var accessor = Storyboard.GetTargetProperty(anim)?.GetAccessor(0) as DependencyProperty;
if (accessor == null)
    throw new InvalidOperationException("First path segment is not a DependencyProperty");

Type guard

bool FirstSegmentIsDependencyProperty(PropertyPath pp) => pp?.GetAccessor(0) is DependencyProperty;

Try / catch

try { sb.Begin(fe); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DependencyProperty")) {
    // fix: point the path at a DependencyProperty
}

Prevention

When it happens

Trigger: Storyboard.TargetProperty references a plain CLR property that is not a DP, or the path's first accessor is not a DependencyProperty (mis-qualified names, unsupported path syntax in storyboard context).

Common situations: Animating ordinary .NET properties on non-DependencyObject classes; typos in attached-property syntax such as writing Canvas.Left without parentheses; wrong casing causing the path parser to bind a non-DP member.

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


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

Appendix: source

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

            // are handled differently.
            using(currentPropertyPath.SetContext(targetObject))
            {
                if( currentPropertyPath.Length < 1 )
                {
                    throw new InvalidOperationException(SR.Storyboard_PropertyPathEmpty);
                }

                VerifyPathIsAnimatable(currentPropertyPath);

                if( currentPropertyPath.Length == 1 )
                {
                    // We have a simple single-step property.
                    targetProperty = currentPropertyPath.GetAccessor(0) as DependencyProperty;

                    if( targetProperty == null )
                    {
                        // Unfortunately it's not a DependencyProperty.
                        throw new InvalidOperationException(SR.Format(SR.Storyboard_PropertyPathMustPointToDependencyProperty, currentPropertyPath.Path ));
                    }

                    VerifyAnimationIsValid(targetProperty, animationClock);

                    ObjectPropertyPair animatedTarget = new ObjectPropertyPair(targetObject, targetProperty);
                    UpdateMappings(clockMappings, animatedTarget, animationClock);
                }
                else // path.Length > 1
                {
                    // This is a multi-step property path that requires more extensive
                    //  setup.
                    ProcessComplexPath(clockMappings, targetObject, currentPropertyPath, animationClock, handoffBehavior, layer);
                }
            }
        }
        else if ( currentClock is MediaClock ) // Not an animation clock - maybe a media clock?
        {
            // Yes it's a media clock.  Try to find the corresponding object and

View on GitHub (pinned to 81131a70a4)