dotnet/wpf · error · InvalidOperationException
SR.Timing_RepeatBehaviorNotRepeatDuration
Error message
SR.Timing_RepeatBehaviorNotRepeatDuration
What it means
RepeatBehavior.Duration returns the stored TimeSpan only when the instance represents a repeat duration (HasDuration). Reading it on an IterationCount-based, Forever, or default RepeatBehavior throws InvalidOperationException with Timing_RepeatBehaviorNotRepeatDuration.
Solutions
- Guard with if (rb.HasDuration) before accessing rb.Duration.
- Handle the IterationCount and Forever cases explicitly instead of defaulting to Duration.
- If a duration is expected, construct with new RepeatBehavior(TimeSpan) and store the TimeSpan alongside instead of re-reading.
Example fix
// before TimeSpan dur = repeatBehavior.Duration; // after TimeSpan dur = repeatBehavior.HasDuration ? repeatBehavior.Duration : TimeSpan.Zero;
Defensive patterns
Strategy: type-guard
Validate before calling
TimeSpan? dur = repeatBehavior.HasDuration ? repeatBehavior.Duration : (TimeSpan?)null;
Type guard
static bool HasRepeatDuration(RepeatBehavior rb) => rb.HasDuration; static TimeSpan? SafeDuration(RepeatBehavior rb) => rb.HasDuration ? rb.Duration : (TimeSpan?)null;
Try / catch
TimeSpan dur;
try { dur = repeatBehavior.Duration; }
catch (InvalidOperationException) { dur = TimeSpan.Zero; } Prevention
- Guard with HasDuration before reading Duration.
- Remember default(RepeatBehavior) supports neither Count nor Duration.
- Keep the original TimeSpan if you constructed with new RepeatBehavior(ts) instead of re-reading.
When it happens
Trigger: Reading rb.Duration when rb = new RepeatBehavior(3), rb == RepeatBehavior.Forever, or rb == default(RepeatBehavior). Only new RepeatBehavior(TimeSpan) instances support Duration.
Common situations: Generic animation inspection code that reads Duration for all repeat behaviors; copying a timeline's RepeatBehavior into a settings object assuming it is duration-based; XAML reload logic.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.Timing_RepeatBehaviorNotIterationCount
- Animation_Invalid_DefaultValue
- SR.Animation_Invalid_DefaultValue
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e2ca03b0ffd48f78.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/RepeatBehavior.cs:126
{
if (!HasCount)
throw new InvalidOperationException(SR.Format(SR.Timing_RepeatBehaviorNotIterationCount, this));
return _iterationCount;
}
}
/// <summary>
/// Returns the repeat duration specified by this RepeatBehavior.
/// </summary>
/// <value>A TimeSpan representing the repeat duration specified by this RepeatBehavior.</value>
/// <exception cref="InvalidOperationException">Thrown if this RepeatBehavior does not represent a repeat duration.</exception>
public TimeSpan Duration
{
get
{
if (!HasDuration)
throw new InvalidOperationException(SR.Format(SR.Timing_RepeatBehaviorNotRepeatDuration, this));
return _repeatDuration;
}
}
/// <summary>
/// Creates and returns a <see cref="RepeatBehavior"/> that indicates that a <see cref="Timeline"/>
/// should repeat its simple duration forever.
/// </summary>
/// <value>A <see cref="RepeatBehavior"/> that indicates that a <see cref="Timeline"/>
/// should repeat its simple duration forever.</value>
public static RepeatBehavior Forever
{
get
{
return new RepeatBehavior(RepeatBehaviorType.Forever);
}
}View on GitHub (pinned to 81131a70a4)