dotnet/wpf · error · InvalidOperationException

Timing_SeekDestinationAmbiguousDueToSlip

Timing_SeekDestinationAmbiguousDueToSlip

Error message

SR.Timing_SeekDestinationAmbiguousDueToSlip (Timing_SeekDestinationAmbiguousDueToSlip)

What it means

During an interactive seek on a ClockGroup with slip behavior, seeking into an Automatic-duration sync child makes the true destination ambiguous — the child's duration is not fixed, so the seek could overseek it. WPF throws InvalidOperationException (Timing_SeekDestinationAmbiguousDueToSlip) rather than guessing a target time.

Solutions

  1. Give the slipping child timeline an explicit TimeSpan Duration so seek destinations are unambiguous
  2. Use SlipBehavior="Grow" instead of Slip on the containing ParallelTimeline
  3. Seek individual child clocks rather than the whole group
  4. Wrap the seek in try/catch for InvalidOperationException and retry after the sync period resolves

Example fix

// before
<ParallelTimeline SlipBehavior="Slip">
  <MediaTimeline Source="clip.wmv" BeginTime="0:0:2" />
</ParallelTimeline>
// after
<ParallelTimeline SlipBehavior="Slip">
  <MediaTimeline Source="clip.wmv" BeginTime="0:0:2" Duration="0:0:10" />
</ParallelTimeline>
Defensive patterns

Strategy: validation

Validate before calling

if (groupTimeline.SlipBehavior == SlipBehavior.Slip && childTimeline.Duration == Duration.Automatic)
    throw new InvalidOperationException("Give slipping sync children an explicit Duration before seeking.");

Try / catch

try { controller.Seek(target, TimeSeekOrigin.Begin); }
catch (InvalidOperationException ex) { /* seek ambiguous: seek child clocks individually or delay */ }

Prevention

When it happens

Trigger: Calling ClockController.Seek/SeekAlignedToLastTick on a ParallelTimeline/Storyboard with SlipBehavior="Slip" whose sync child has Duration.Automatic, while the clock is inside its sync period (HasSlip configured, e.g. media children).

Common situations: Storyboards containing MediaTimeline (video) children with SlipBehavior.Slip; developers seek the storyboard while video is playing and the target time falls inside an automatic-duration segment.

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/f37c6c4e8366f6ab. Report an issue: GitHub.

Appendix: source

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

                            {
                                // If the sync child has a specified duration
                                Duration syncClockDuration = _syncData.SyncClockResolvedDuration;

                                if (syncClockDuration.HasTimeSpan)
                                {
                                    _syncData.PreviousSyncClockTime = TimeSpan.FromTicks(ourSyncTimeST.Ticks % syncClockDuration.TimeSpan.Ticks);
                                    _syncData.PreviousRepeatTime = ourSyncTimeST - _syncData.PreviousSyncClockTime;
                                }
                                else if (syncClockDuration == Duration.Forever)
                                {
                                    _syncData.PreviousSyncClockTime = ourSyncTimeST;
                                    _syncData.PreviousRepeatTime = TimeSpan.Zero;
                                }
                                else
                                {
                                    Debug.Assert(syncClockDuration == Duration.Automatic);
                                    // If we seek into an Automatic syncChild's duration, we may overseek it, so throw an exception
                                    throw new InvalidOperationException(SR.Timing_SeekDestinationAmbiguousDueToSlip);
                                }

                                // This is the heart of the HasSeekOccuredAfterLastTick codepath; we don't adjust our
                                // time, but note to do so for the succeeding ticks.
                                _syncData.IsInSyncPeriod = true;
                            }
                        }
                    }
                    else  // Non-seek, regular case
                    {
                        TimeSpan? previousSyncParentTimeSPT = (_syncData.SyncClock == this) ?
                                                             parentIntervalCollection.FirstNodeTime :
                                                             _currentTime;

                        if (!previousSyncParentTimeSPT.HasValue
                            || _syncData.SyncClockDiscontinuousEvent
                            || previousSyncParentTimeSPT.Value <= _syncData.SyncClockBeginTime)
                        // Not seeking this tick, different criteria for entering sync period.

View on GitHub (pinned to 81131a70a4)