dotnet/wpf · error · ArgumentOutOfRangeException

SR.Timing_RepeatBehaviorInvalidRepeatDuration

Error message

SR.Timing_RepeatBehaviorInvalidRepeatDuration

What it means

The RepeatBehavior(TimeSpan duration) constructor rejects negative TimeSpans with ArgumentOutOfRangeException carrying Timing_RepeatBehaviorInvalidRepeatDuration. A repeat duration defines how long the animation repeats, and a negative duration is meaningless to the timing engine.

Solutions

  1. Check duration >= TimeSpan.Zero before constructing (use TimeSpan.Compare or the >= operator).
  2. Clamp with duration < TimeSpan.Zero ? TimeSpan.Zero : duration.
  3. If you need zero-length repeat, pass TimeSpan.Zero; if infinite, use RepeatBehavior.Forever.

Example fix

// before
var rb = new RepeatBehavior(end - start); // end < start
// after
var dur = end - start;
var rb = new RepeatBehavior(dur >= TimeSpan.Zero ? dur : TimeSpan.Zero);
Defensive patterns

Strategy: validation

Validate before calling

if (duration < TimeSpan.Zero) duration = TimeSpan.Zero;
var rb = new RepeatBehavior(duration);

Type guard

static bool IsValidRepeatDuration(TimeSpan d) => d >= TimeSpan.Zero;

Try / catch

RepeatBehavior rb;
try { rb = new RepeatBehavior(duration); }
catch (ArgumentOutOfRangeException) { rb = new RepeatBehavior(TimeSpan.Zero); }

Prevention

When it happens

Trigger: new RepeatBehavior(TimeSpan.FromSeconds(-5)) or computing the duration from a value that can go negative (e.g., endTime - startTime where the inputs were reversed).

Common situations: Subtracting DateTime/TimeSpan endpoints in the wrong order; loading a negative duration from config or user input; converting seconds to TimeSpan with a negative multiplier.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/0393c60fb117dab7. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/RepeatBehavior.cs:54

        public RepeatBehavior(double count)
        {
            if (double.IsInfinity(count) || double.IsNaN(count) || count < 0.0)
                throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.Timing_RepeatBehaviorInvalidIterationCount, count));

            _repeatDuration = TimeSpan.Zero;
            _iterationCount = count;
            _type = RepeatBehaviorType.IterationCount;
        }

        /// <summary>
        /// Creates a new RepeatBehavior that represents a repeat duration for which a Timeline will repeat
        /// its simple duration.
        /// </summary>
        /// <param name="duration">A TimeSpan representing the repeat duration specified by this RepeatBehavior.</param>
        public RepeatBehavior(TimeSpan duration)
        {
            if (duration < TimeSpan.Zero)
                throw new ArgumentOutOfRangeException(nameof(duration), SR.Format(SR.Timing_RepeatBehaviorInvalidRepeatDuration, duration));

            _iterationCount = 0.0;
            _repeatDuration = duration;
            _type = RepeatBehaviorType.RepeatDuration;
        }

        /// <summary>
        /// Private constructor, serves for creation of <see cref="RepeatBehavior.Forever"/> only.
        /// </summary>
        /// <param name="behaviorType">Only <see cref="RepeatBehaviorType.Forever"/> value is permitted.</param>
        private RepeatBehavior(RepeatBehaviorType behaviorType)
        {
            Debug.Assert(behaviorType == RepeatBehaviorType.Forever);

            _type = behaviorType;
        }

        #endregion // Constructors

View on GitHub (pinned to 81131a70a4)