dotnet/wpf · error · InvalidOperationException
Timing_CreateClockMustReturnNewClock
Timing_CreateClockMustReturnNewClock
Error message
SR.Timing_CreateClockMustReturnNewClock (Timing_CreateClockMustReturnNewClock)
What it means
AllocateClock verified that the Clock returned by a Timeline-derived class's CreateClock override is brand new: not already parented and not already attached to a clock group's children. A recycled or shared clock fails this invariant and WPF throws InvalidOperationException.
Solutions
- Always create a fresh Clock instance in the CreateClock override
- Remove clock caching/pooling from custom Timeline subclasses
- Verify the custom clock constructor does not attach itself to a parent or group
Example fix
// before public override Clock CreateClock() => _cachedClock ??= base.CreateClock(); // throws on reuse // after public override Clock CreateClock() => base.CreateClock();
Defensive patterns
Strategy: validation
Validate before calling
Debug.Assert(myClock.Parent == null, "Clock must be fresh, not reused");
Try / catch
try { var clock = timeline.CreateClock(); } catch (InvalidOperationException ex) { log.Error(ex); } Prevention
- Never cache or pool Clock instances
- Create a new Clock in every CreateClock override
When it happens
Trigger: Overriding CreateClock in a custom Timeline and returning a cached/shared Clock instance; calling CreateClock twice and reusing the first result.
Common situations: Custom timeline implementations that pool clocks for performance; factory code accidentally reusing a clock across timelines.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- SR.Media_NotAllowedWhileTimingEngineInControl
- Timing_SkipToFillDestinationIndefinite
- Animation_AnimationTimelineTypeMismatch
- Animation_CalculatedValueIsInvalidForProperty
- Animation_ChildMustBeKeyFrame
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/6fa21b98a614ec65.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Clock.cs:582
internal static Clock AllocateClock(
Timeline timeline,
bool hasControllableRoot)
{
Clock clock = timeline.AllocateClock();
// Assert that we weren't given an existing clock
Debug.Assert(!clock.IsTimeManager);
ClockGroup clockGroup = clock as ClockGroup;
if ( clock._parent != null
|| ( clockGroup != null
&& clockGroup.InternalChildren != null ))
{
// The derived class is trying to fool us -- we require a new,
// fresh, unassociated clock here
throw new InvalidOperationException(
SR.Format(
SR.Timing_CreateClockMustReturnNewClock,
timeline.GetType().Name));
}
clock.SetFlag(ClockFlags.HasControllableRoot, hasControllableRoot);
return clock;
}
internal virtual void BuildClockSubTreeFromTimeline(
Timeline timeline,
bool hasControllableRoot)
{
SetFlag(ClockFlags.CanSlip, GetCanSlip()); // Set the CanSlip flag
// Here we preview the clock's own slip-ability, hence ClockGroups should return false
// at this stage, because their children are not yet added by the time of this call.View on GitHub (pinned to 81131a70a4)