{"record":{"id":"26bfeebe8f264c0d","repo":"AvaloniaUI/Avalonia","slug":"invalid-animation-duration","errorCode":null,"errorMessage":"Invalid animation duration","messagePattern":"Invalid animation duration","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs","lineNumber":53,"sourceCode":"            AnimationIterationBehavior iterationBehavior,\n            int iterationCount, AnimationStopBehavior stopBehavior) : base(target, snapshot)\n        {\n            _interpolator = interpolator;\n            _keyFrames = keyFrames;\n            _finalValue = finalValue;\n            _delayBehavior = delayBehavior;\n            _delayTime = delayTime;\n            _direction = direction;\n            _duration = duration;\n            _iterationBehavior = iterationBehavior;\n            _iterationCount = iterationCount;\n            _stopBehavior = stopBehavior;\n            if (_iterationBehavior == AnimationIterationBehavior.Count)\n                _totalDuration = delayTime.Add(TimeSpan.FromTicks(iterationCount * _duration.Ticks));\n            if (_keyFrames.Length == 0)\n                throw new InvalidOperationException(\"Animation has no key frames\");\n            if(_duration.Ticks <= 0)\n                throw new InvalidOperationException(\"Invalid animation duration\");\n        }\n\n\n        protected override ExpressionVariant EvaluateCore(TimeSpan now, ExpressionVariant currentValue)\n        {\n            var starting = ExpressionVariant.Create(_startingValue);\n            var ctx = new ExpressionEvaluationContext\n            {\n                Parameters = Parameters,\n                Target = TargetObject,\n                CurrentValue = currentValue,\n                FinalValue = _finalValue ??  starting,\n                StartingValue = starting,\n                ForeignFunctionInterface = BuiltInExpressionFfi.Instance\n            };\n            var elapsed = now - _startedAt;\n            var res = EvaluateImpl(elapsed, currentValue, ref ctx);\n            ","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs#L35-L71","documentation":"Thrown by the KeyFrameAnimationInstance constructor when duration.Ticks <= 0. Even though the KeyFrameAnimation.Duration setter is supposed to enforce a minimum of 1ms, the instance constructor re-validates defensively; a non-positive duration makes iteration-count math and time interpolation undefined.","triggerScenarios":"Passing a Duration of TimeSpan.Zero or negative into a composition animation instance. Because of the KeyFrameAnimation.Duration setter bug (it validates the wrong variable), a zero/negative duration can slip through to here.","commonSituations":"Duration computed from a multiplier that yields zero; relying on the setter to reject zero but hitting the buggy _duration check; constructing a KeyFrameAnimationInstance directly with a default TimeSpan.","solutions":["Ensure Duration is at least TimeSpan.FromMilliseconds(1) before starting the animation.","Guard the duration against <= TimeSpan.Zero and fall back to a sane default.","If maintaining the library, also fix KeyFrameAnimation.Duration to validate the incoming value so this constructor never receives an invalid duration."],"exampleFix":"// before\nanim.Duration = computed; // computed is TimeSpan.Zero\nvisual.StartAnimation(\"Opacity\", anim); // throws in instance ctor\n// after\nanim.Duration = computed > TimeSpan.Zero ? computed : TimeSpan.FromMilliseconds(250);","handlingStrategy":"validation","validationCode":"if (duration <= TimeSpan.Zero) duration = TimeSpan.FromMilliseconds(250);\nanim.Duration = duration;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass TimeSpan.Zero or negative as a duration.","Guard computed durations with a positive fallback.","Remember the Duration setter's validation is buggy, so validate at the call site too."],"tags":["animation","composition","invalid-operation","timespan","defensive-check"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}