{"record":{"id":"7b4d78c4e45e0158","repo":"dotnet/wpf","slug":"sr-timing-invalidargnonnegative","errorCode":null,"errorMessage":"SR.Timing_InvalidArgNonNegative","messagePattern":"SR\\.Timing_InvalidArgNonNegative","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Duration.cs","lineNumber":26,"sourceCode":"{\n    /// <summary>\n    /// Duration struct provides sentinel values that are not included in TimeSpan.\n    /// This structure may represent a TimeSpan, Automatic, or Forever value.\n    /// </summary>\n    [TypeConverter(typeof(DurationConverter))]\n    public readonly struct Duration\n    {\n        private readonly TimeSpan _timeSpan;\n        private readonly DurationType _durationType;\n\n        /// <summary>\n        /// Creates a Duration from a TimeSpan.\n        /// </summary>\n        /// <param name=\"timeSpan\"></param>\n        public Duration(TimeSpan timeSpan)\n        {\n            if (timeSpan < TimeSpan.Zero)\n                throw new ArgumentException(SR.Timing_InvalidArgNonNegative, nameof(timeSpan));\n\n            _durationType = DurationType.TimeSpan;\n            _timeSpan = timeSpan;\n        }\n\n        /// <summary>\n        /// Private constructor, server for creation of <see cref=\"Duration.Automatic\"/> and <see cref=\"Duration.Forever\"/> only.\n        /// </summary>\n        /// <param name=\"durationType\">Only <see cref=\"Duration.Automatic\"/> and <see cref=\"Duration.Forever\"/> values are permitted.</param>\n        private Duration(DurationType durationType)\n        {\n            Debug.Assert(durationType == DurationType.Automatic || durationType == DurationType.Forever);\n\n            _durationType = durationType;\n        }\n\n        #region Operators\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Duration.cs#L8-L44","documentation":"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.","triggerScenarios":"new Duration(TimeSpan.FromMilliseconds(-1)) or any negative TimeSpan, commonly produced by subtracting TimeSpans or computing a remaining-time that underflows.","commonSituations":"Computing animation durations from deadlines that already passed (endTime - now < 0); converting signed durations from other systems; configuration parsing yielding negative values.","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."],"exampleFix":"// before\nvar duration = new Duration(endTime - DateTime.Now); // negative if past\n// after\nvar remaining = endTime - DateTime.Now;\nvar duration = new Duration(remaining > TimeSpan.Zero ? remaining : TimeSpan.Zero);","handlingStrategy":"validation","validationCode":"if (timeSpan < TimeSpan.Zero) timeSpan = TimeSpan.Zero;","typeGuard":"static bool IsNonNegative(TimeSpan t) => t >= TimeSpan.Zero;","tryCatchPattern":"try { var d = new Duration(ts); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"greater than or equal to zero\")) { var d = Duration.Forever; }","preventionTips":["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."],"tags":["wpf","animation","duration","argument-exception"],"backgroundTag":"argument-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}