AvaloniaUI/Avalonia · error · InvalidOperationException

Duration value cannot be negative.

Error message

Duration value cannot be negative.

What it means

Thrown by AnimationInstance<T>.FetchProperties (called from the constructor) when the Animation.Duration property is set to a negative TimeSpan. Avalonia clamps/validates timing fields at animation startup because the internal time-accumulator logic cannot represent backwards durations. This guard runs every time an animation instance is constructed and reads the current Duration value.

Source

Thrown at src/Avalonia.Base/Animation/AnimationInstance`1.cs:97

            FetchProperties();
        }

        private void FetchProperties()
        {
            _easeFunc = _animation.Easing;

            _speedRatioPrev = _speedRatio;
            _speedRatio = _animation.SpeedRatio;
            if (_speedRatio < 0d)
                throw new InvalidOperationException("SpeedRatio value cannot be negative.");

            _initialDelay = _animation.Delay;
            if (_initialDelay < TimeSpan.Zero)
                throw new InvalidOperationException("Delay value cannot be negative.");

            _duration = _animation.Duration;
            if (_duration < TimeSpan.Zero)
                throw new InvalidOperationException("Duration value cannot be negative.");

            _iterationDelay = _animation.DelayBetweenIterations;
            if (_iterationDelay < TimeSpan.Zero)
                throw new InvalidOperationException("DelayBetweenIterations value cannot be negative.");

            if (_animation.IterationCount.RepeatType == IterationType.Many)
            {
                if (_animation.IterationCount.Value > long.MaxValue)
                    throw new InvalidOperationException("IterationCount value cannot be larger than long.MaxValue.");
                _iterationCount = (long)_animation.IterationCount.Value;
            }
            else
            {
                _iterationCount = null;
            }

            _playbackDirectionPrev = _playbackDirection;
            _playbackDirection = _animation.PlaybackDirection;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Clamp Duration to TimeSpan.Zero before running: animation.Duration = source < TimeSpan.Zero ? TimeSpan.Zero : source.
  2. Fix the upstream computation that produced a negative duration (e.g. swap operand order in a subtraction).
  3. Guard the value at the data source / model layer before assigning it to the Animation.

Example fix

// before
animation.Duration = TimeSpan.FromSeconds(endTime - startTime); // negative when endTime < startTime

// after
animation.Duration = TimeSpan.FromTicks(Math.Max(0, (endTime - startTime).Ticks));
Defensive patterns

Strategy: validation

Validate before calling

if (animation.Duration < TimeSpan.Zero)
    throw new ArgumentOutOfRangeException(nameof(animation.Duration), "Duration must be non-negative.");

Prevention

When it happens

Trigger: Constructing/running an Animation whose Duration is set to a negative value (e.g. TimeSpan.FromSeconds(-1)). Fires inside AnimationInstance ctor -> FetchProperties when _animation.Duration < TimeSpan.Zero.

Common situations: Computing Duration from a difference of two timestamps where start > end yields a negative span; binding Duration from a model property that is uninitialized (-1 sentinel); deserializing XAML/JSON with a typo'd negative number.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/7e338e8b842458fd. Report an issue: GitHub.