dotnet/wpf · error · NotSupportedException
Timing_SlipBehavior_SlipOnlyOnSimpleTimelines
Timing_SlipBehavior_SlipOnlyOnSimpleTimelines
Error message
SR.Timing_SlipBehavior_SlipOnlyOnSimpleTimelines (Timing_SlipBehavior_SlipOnlyOnSimpleTimelines)
What it means
SlipBehavior.Slip is only supported on root clock trees with simple timelines: the root may not have a RepeatBehavior with a Duration, AutoReverse, or non-zero Acceleration/Deceleration ratios, otherwise child slipping cannot be tracked. BuildClockSubTreeFromTimeline throws NotSupportedException (Timing_SlipBehavior_SlipOnlyOnSimpleTimelines) when those conditions are violated.
Solutions
- Set SlipBehavior="Grow" (default) instead of Slip
- Remove AutoReverse, AccelerationRatio/DecelerationRatio, and duration-based RepeatBehavior from the root timeline
- Apply easing/acceleration to individual child animations instead of the slipping root
- Move the slipping media child into a simpler nested timeline structure
Example fix
// before <Storyboard SlipBehavior="Slip" AutoReverse="True"> <MediaTimeline Source="clip.wmv" /> </Storyboard> // throws // after <Storyboard SlipBehavior="Slip"> <MediaTimeline Source="clip.wmv" /> </Storyboard>
Defensive patterns
Strategy: validation
Validate before calling
bool slipAllowed = timeline.SlipBehavior != SlipBehavior.Slip
|| !timeline.RepeatBehavior.HasDuration
&& !timeline.AutoReverse
&& timeline.AccelerationRatio == 0
&& timeline.DecelerationRatio == 0;
if (!slipAllowed) timeline.SlipBehavior = SlipBehavior.Grow; Try / catch
try { storyboard.Begin(this, true); }
catch (NotSupportedException ex) when (ex.Message.Contains("Slip")) { /* switch SlipBehavior to Grow and retry */ } Prevention
- Keep slipping root timelines simple: no AutoReverse, easing ratios, or duration RepeatBehavior
- Apply easing/acceleration on child animations, not slipping roots
- Default to SlipBehavior.Grow unless media-sync slipping is explicitly required
When it happens
Trigger: Creating a Clock/Storyboard with SlipBehavior="Slip" on a timeline that also sets RepeatBehavior with Duration, AutoReverse="True", AccelerationRatio>0, or DecelerationRatio>0 (on the root).
Common situations: Combining video MediaTimeline slipping with eased/fancied-up root timelines; applying global storyboard easing or looping (RepeatBehavior="2x"/AutoReverse) to a storyboard that contains a media child with slip.
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
- 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/b4a005290a4e0d7d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/ClockGroup.cs:127
childClock = AllocateClock(timelineChildren[index], hasControllableRoot);
childClock._parent = this; // We connect the child to the subtree before calling BuildClockSubtreeFromTimeline
childClock.BuildClockSubTreeFromTimeline(timelineChildren[index], hasControllableRoot);
_children.Add(childClock);
childClock._childIndex = index;
}
// If we have SlipBehavior, check if we have any childen with which to slip.
if (_timeline is ParallelTimeline &&
((ParallelTimeline)_timeline).SlipBehavior == SlipBehavior.Slip)
{
// Verify that we only use SlipBehavior in supported scenarios
if (!IsRoot ||
(_timeline.RepeatBehavior.HasDuration) ||
(_timeline.AutoReverse) ||
(_timeline.AccelerationRatio > 0) ||
(_timeline.DecelerationRatio > 0))
{
throw new NotSupportedException(SR.Timing_SlipBehavior_SlipOnlyOnSimpleTimelines);
}
for (int index = 0; index < _children.Count; index++)
{
Clock child = _children[index];
if (child.CanSlip)
{
Duration duration = child.ResolvedDuration;
// A sync clock with duration of zero or no begin time has no effect, so do skip it
if ((!duration.HasTimeSpan || duration.TimeSpan > TimeSpan.Zero)
&& child._timeline.BeginTime.HasValue)
{
_syncData = new SyncData(child);
child._syncData = null; // The child will no longer self-sync
}
break; // We only want the first child with CanSlipView on GitHub (pinned to 81131a70a4)