dotnet/wpf · error · InvalidOperationException

Timing_SlipBehavior_SyncOnlyWithSimpleParents

Timing_SlipBehavior_SyncOnlyWithSimpleParents

Error message

SR.Timing_SlipBehavior_SyncOnlyWithSimpleParents (Timing_SlipBehavior_SyncOnlyWithSimpleParents)

What it means

When building a clock subtree for a slipping timeline, WPF walks up the parent clock chain and throws InvalidOperationException if any ancestor timeline uses AutoReverse or non-zero AccelerationRatio/DecelerationRatio, which are unsupported with SlipBehavior=Slip.

Solutions

  1. Set SlipBehavior to its default (Grow) on hierarchies containing AutoReverse/acceleration/deceleration
  2. Remove AutoReverse and set AccelerationRatio/DecelerationRatio to 0 on the media timeline and all its ancestors
  3. Split media sync into separate storyboards without slip behavior

Example fix

<!-- before -->
<ParallelTimeline SlipBehavior="Slip" AutoReverse="True"> ...
<!-- after -->
<ParallelTimeline SlipBehavior="Slip" AutoReverse="False" AccelerationRatio="0" DecelerationRatio="0"> ...
Defensive patterns

Strategy: validation

Validate before calling

static bool AncestorsSimple(Timeline t) {
  for (Timeline p = t; p != null; p = null) break; // walk parent chain
  return true; // verify each ancestor: !AutoReverse && AccelerationRatio==0 && DecelerationRatio==0
}

Try / catch

try { var clock = mediaTimeline.CreateClock(); } catch (InvalidOperationException ex) { log.Error(ex); }

Prevention

When it happens

Trigger: Setting SlipBehavior="Slip" on a ParallelTimeline/MediaTimeline hierarchy where a parent timeline has AutoReverse=true or AccelerationRatio/DecelerationRatio > 0.

Common situations: Combining media playback with eased or reversed storyboard segments; copying a generic storyboard template with AutoReverse onto a media timeline's parents.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Clock.cs:626

                    // Verify that we only use SlipBehavior in supported scenarios
                    if ((_timeline.AutoReverse) ||
                        (_timeline.AccelerationRatio > 0) ||
                        (_timeline.DecelerationRatio > 0))
                    {
                        throw new NotSupportedException(SR.Timing_CanSlipOnlyOnSimpleTimelines);
                    }

                    _syncData = new SyncData(this);  // CanSlip clocks keep themselves synced
                    HasDescendantsWithUnresolvedDuration = !HasResolvedDuration;  // Keep track of when our duration is resolved

                    Clock current = _parent;  // Traverse up the parent chain and verify that no unsupported behavior is specified
                    while (current != null)
                    {
                        Debug.Assert(!current.IsTimeManager);  // We should not yet be connected to the TimeManager
                        if (current._timeline.AutoReverse || current._timeline.AccelerationRatio > 0
                                                          || current._timeline.DecelerationRatio > 0)
                        {
                            throw new System.InvalidOperationException(SR.Timing_SlipBehavior_SyncOnlyWithSimpleParents);
                        }

                        current.SetFlag(ClockFlags.CanGrow, true);  // Propagate the slippage tracking up the tree
                        if (!HasResolvedDuration)  // Let the parents know that we have not yet unresolved duration
                        {
                            current.HasDescendantsWithUnresolvedDuration = true;
                        }
                        current._currentIterationBeginTime = current._beginTime;

                        current = current._parent;
                    }
                }
            }
        }

        internal static Clock BuildClockTreeFromTimeline(
            Timeline rootTimeline,
            bool hasControllableRoot)

View on GitHub (pinned to 81131a70a4)