dotnet/wpf · error · InvalidOperationException
SR.Timing_NotTimeSpan
Error message
SR.Timing_NotTimeSpan
What it means
Duration.TimeSpan throws InvalidOperationException when the Duration instance does not hold a TimeSpan value (e.g. it is Duration.Automatic or Duration.Forever). The WPF Duration type is a union of a TimeSpan, Automatic, and Forever states, and this accessor is only valid for the TimeSpan state. The library throws to force callers to check HasTimeSpan before unwrapping the value.
Solutions
- Check the HasTimeSpan property before reading .TimeSpan
- Handle Duration.Forever and Duration.Automatic explicitly in branching logic
- If a finite default is required, normalize: use duration.HasTimeSpan ? duration.TimeSpan : someFallback
Example fix
// before
TimeSpan ts = storyboard.Duration.TimeSpan;
// after
if (storyboard.Duration.HasTimeSpan)
TimeSpan ts = storyboard.Duration.TimeSpan;
else
TimeSpan ts = TimeSpan.FromSeconds(1); // fallback for Automatic/Forever Defensive patterns
Strategy: validation
Validate before calling
if (duration != null && duration.HasTimeSpan) { var ts = duration.TimeSpan; } Type guard
bool HasFiniteDuration(Duration d) => d != null && d.HasTimeSpan;
Try / catch
try { var ts = d.TimeSpan; } catch (InvalidOperationException) { /* Automatic/Forever: use fallback */ } Prevention
- Always gate .TimeSpan access behind HasTimeSpan
- Treat Duration.Automatic/Forever as distinct states in branch logic
- Add a GetTimeSpanOrFallback helper in shared animation code
When it happens
Trigger: Accessing the .TimeSpan property on a Duration whose HasTimeSpan is false — e.g. `Duration.Forever.TimeSpan`, `Duration.Automatic.TimeSpan`, or a Duration built via Duration.Automatic/Forever or the Duration(DurationType) constructor.
Common situations: Animation code reading a Duration that came from XAML set to "Automatic" or "Forever"; interop code assuming all Durations are finite; defaults set to Duration.Automatic then blindly read back.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Animation_Invalid_DefaultValue
- SR.Animation_Invalid_DefaultValue
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/644b7c6aeb27f7d1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Duration.cs:395
/// <value>A Duration that represents a Forever value.</value>
public static Duration Forever
{
get
{
return new Duration(DurationType.Forever);
}
}
/// <summary>
/// Returns the TimeSpan value that this Duration represents.
/// </summary>
/// <value>The TimeSpan value that this Duration represents.</value>
/// <exception cref="InvalidOperationException">Thrown if this Duration represents null.</exception>
public TimeSpan TimeSpan
{
get
{
return HasTimeSpan ? _timeSpan : throw new InvalidOperationException(SR.Format(SR.Timing_NotTimeSpan, this));
}
}
#endregion
#region Methods
/// <summary>
/// Adds the specified Duration to this instance.
/// </summary>
/// <param name="duration"></param>
/// <returns>A Duration that represents the value of this instance plus the value of duration.</returns>
public Duration Add(Duration duration)
{
return this + duration;
}
/// <summary>View on GitHub (pinned to 81131a70a4)