dotnet/wpf · error · InvalidOperationException
SR.Timing_RepeatBehaviorNotIterationCount
Error message
SR.Timing_RepeatBehaviorNotIterationCount
What it means
RepeatBehavior.Count returns the iteration count only when the instance represents one (HasCount / KeyTimeType-style IterationCount). Reading Count on a RepeatBehavior created as Forever, a RepeatBehavior(TimeSpan), or the default throws InvalidOperationException with Timing_RepeatBehaviorNotIterationCount.
Solutions
- Guard with if (rb.HasCount) before accessing rb.Count.
- Branch on the behavior: HasCount -> Count, HasDuration -> Duration, Forever -> infinite handling.
- Do not treat Count as a numeric fallback; use HasCount/HasDuration to pick the property.
Example fix
// before double count = repeatBehavior.Count; // after double count = repeatBehavior.HasCount ? repeatBehavior.Count : 0;
Defensive patterns
Strategy: type-guard
Validate before calling
double? count = repeatBehavior.HasCount ? repeatBehavior.Count : (double?)null;
Type guard
static bool HasIterationCount(RepeatBehavior rb) => rb.HasCount; static double? SafeCount(RepeatBehavior rb) => rb.HasCount ? rb.Count : (double?)null;
Try / catch
double count;
try { count = repeatBehavior.Count; }
catch (InvalidOperationException) { count = 0; } Prevention
- Check HasCount / HasDuration / Forever before reading Count or Duration.
- Treat RepeatBehavior as a discriminated union, not a plain struct with always-valid fields.
- In serialization code, branch on the behavior type explicitly.
When it happens
Trigger: Reading rb.Count when rb was built with new RepeatBehavior(TimeSpan.FromSeconds(2)), is RepeatBehavior.Forever, or is default(RepeatBehavior). Example: double n = RepeatBehavior.Forever.Count; throws.
Common situations: Serializing animation settings without checking the behavior type; UI code that assumes every RepeatBehavior has a count; migrating code that used an older API where count was always set.
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_RepeatBehaviorNotRepeatDuration
- 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/bc25d2c07f98cad4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/RepeatBehavior.cs:110
public bool HasDuration
{
get
{
return _type == RepeatBehaviorType.RepeatDuration;
}
}
/// <summary>
/// Returns the iteration count specified by this RepeatBehavior.
/// </summary>
/// <value>The iteration count specified by this RepeatBehavior.</value>
/// <exception cref="InvalidOperationException">Thrown if this RepeatBehavior does not represent an iteration count.</exception>
public double Count
{
get
{
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;View on GitHub (pinned to 81131a70a4)