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

  1. Check the HasTimeSpan property before reading .TimeSpan
  2. Handle Duration.Forever and Duration.Automatic explicitly in branching logic
  3. 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

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


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)