dotnet/wpf · error · ArgumentException
SR.Timing_InvalidArgNonNegative
Error message
SR.Timing_InvalidArgNonNegative
What it means
The Duration(TimeSpan) constructor creates a duration used by WPF animation timing. Negative TimeSpans are meaningless as durations, so the constructor throws ArgumentException ("Property value must be greater than or equal to zero or indefinite.") when timeSpan < TimeSpan.Zero.
Solutions
- Clamp computed TimeSpans to TimeSpan.Zero before constructing a Duration.
- Use Duration.Forever or Duration.Automatic for indefinite/special semantics instead of a negative value.
- Validate configuration inputs so negative durations are rejected or coerced at parse time.
Example fix
// before var duration = new Duration(endTime - DateTime.Now); // negative if past // after var remaining = endTime - DateTime.Now; var duration = new Duration(remaining > TimeSpan.Zero ? remaining : TimeSpan.Zero);
Defensive patterns
Strategy: validation
Validate before calling
if (timeSpan < TimeSpan.Zero) timeSpan = TimeSpan.Zero;
Type guard
static bool IsNonNegative(TimeSpan t) => t >= TimeSpan.Zero;
Try / catch
try { var d = new Duration(ts); }
catch (ArgumentException ex) when (ex.Message.Contains("greater than or equal to zero")) { var d = Duration.Forever; } Prevention
- Clamp computed remaining-time values with TimeSpan.Max(zero).
- Use Duration.Forever/Duration.Automatic for indefinite cases.
- Validate deserialized/config duration strings for a leading '-' before parsing.
When it happens
Trigger: new Duration(TimeSpan.FromMilliseconds(-1)) or any negative TimeSpan, commonly produced by subtracting TimeSpans or computing a remaining-time that underflows.
Common situations: Computing animation durations from deadlines that already passed (endTime - now < 0); converting signed durations from other systems; configuration parsing yielding negative values.
Related errors
- SR.Animation_AnimationTimelineTypeMismatch
- SR.Animation_UnrecognizedHandoffBehavior
- SR.Animation_UnrecognizedHandoffBehavior
- SR.Format(SR.Animation_AnimationTimelineTypeMismatch…
- SR.Format(SR.Animation_AnimationTimelineTypeMismatch…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7b4d78c4e45e0158.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Duration.cs:26
{
/// <summary>
/// Duration struct provides sentinel values that are not included in TimeSpan.
/// This structure may represent a TimeSpan, Automatic, or Forever value.
/// </summary>
[TypeConverter(typeof(DurationConverter))]
public readonly struct Duration
{
private readonly TimeSpan _timeSpan;
private readonly DurationType _durationType;
/// <summary>
/// Creates a Duration from a TimeSpan.
/// </summary>
/// <param name="timeSpan"></param>
public Duration(TimeSpan timeSpan)
{
if (timeSpan < TimeSpan.Zero)
throw new ArgumentException(SR.Timing_InvalidArgNonNegative, nameof(timeSpan));
_durationType = DurationType.TimeSpan;
_timeSpan = timeSpan;
}
/// <summary>
/// Private constructor, server for creation of <see cref="Duration.Automatic"/> and <see cref="Duration.Forever"/> only.
/// </summary>
/// <param name="durationType">Only <see cref="Duration.Automatic"/> and <see cref="Duration.Forever"/> values are permitted.</param>
private Duration(DurationType durationType)
{
Debug.Assert(durationType == DurationType.Automatic || durationType == DurationType.Forever);
_durationType = durationType;
}
#region Operators
View on GitHub (pinned to 81131a70a4)