{"record":{"id":"6fa21b98a614ec65","repo":"dotnet/wpf","slug":"timing-createclockmustreturnnewclock","errorCode":"Timing_CreateClockMustReturnNewClock","errorMessage":"SR.Timing_CreateClockMustReturnNewClock (Timing_CreateClockMustReturnNewClock)","messagePattern":"SR\\.Timing_CreateClockMustReturnNewClock \\(Timing_CreateClockMustReturnNewClock\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Clock.cs","lineNumber":582,"sourceCode":"\n        internal static Clock AllocateClock(\n            Timeline timeline,\n            bool hasControllableRoot)\n        {\n            Clock clock = timeline.AllocateClock();\n\n            // Assert that we weren't given an existing clock\n            Debug.Assert(!clock.IsTimeManager);\n\n            ClockGroup clockGroup = clock as ClockGroup;\n\n            if (   clock._parent != null\n                || (   clockGroup != null\n                    && clockGroup.InternalChildren != null ))\n            {\n                // The derived class is trying to fool us -- we require a new,\n                // fresh, unassociated clock here\n                throw new InvalidOperationException(\n                    SR.Format(\n                        SR.Timing_CreateClockMustReturnNewClock,\n                        timeline.GetType().Name));\n            }\n\n            clock.SetFlag(ClockFlags.HasControllableRoot, hasControllableRoot);\n\n            return clock;\n        }\n\n        internal virtual void BuildClockSubTreeFromTimeline(\n            Timeline timeline,\n            bool hasControllableRoot)\n        {\n            SetFlag(ClockFlags.CanSlip, GetCanSlip());  // Set the CanSlip flag\n\n            // Here we preview the clock's own slip-ability, hence ClockGroups should return false\n            // at this stage, because their children are not yet added by the time of this call.","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Clock.cs#L564-L600","documentation":"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.","triggerScenarios":"Overriding CreateClock in a custom Timeline and returning a cached/shared Clock instance; calling CreateClock twice and reusing the first result.","commonSituations":"Custom timeline implementations that pool clocks for performance; factory code accidentally reusing a clock across timelines.","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"],"exampleFix":"// before\npublic override Clock CreateClock() => _cachedClock ??= base.CreateClock(); // throws on reuse\n// after\npublic override Clock CreateClock() => base.CreateClock();","handlingStrategy":"validation","validationCode":"Debug.Assert(myClock.Parent == null, \"Clock must be fresh, not reused\");","typeGuard":null,"tryCatchPattern":"try { var clock = timeline.CreateClock(); } catch (InvalidOperationException ex) { log.Error(ex); }","preventionTips":["Never cache or pool Clock instances","Create a new Clock in every CreateClock override"],"tags":["wpf","animation","clock","custom-timeline"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}