{"record":{"id":"eed3c0dcba9e47bc","repo":"dotnet/wpf","slug":"valuespan-is-not-a-valid-value-for-nameof-timespan","errorCode":null,"errorMessage":"{valueSpan} is not a valid value for {nameof(TimeSpan)}.","messagePattern":"(.+?) is not a valid value for (.+?)\\.","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/DurationConverter.cs","lineNumber":80,"sourceCode":"        }\n\n        /// <summary>\n        /// Facilities parsing from <paramref name=\"valueSpan\"/> to <see cref=\"TimeSpan\"/> and initializes new <see cref=\"Duration\"/> instance.\n        /// </summary>\n        /// <param name=\"valueSpan\">The string to convert from.</param>\n        /// <param name=\"cultureInfo\">The culture specifier to use.</param>\n        /// <returns>A newly initialized <see cref=\"Duration\"/> instance from the <paramref name=\"valueSpan\"/> string.</returns>\n        /// <remarks>This function is decoupled from the <see cref=\"ConvertFrom(ITypeDescriptorContext, CultureInfo, object)\"/> for performance reasons.</remarks>\n        /// <exception cref=\"FormatException\">Thrown when parsing of <paramref name=\"valueSpan\"/> to <see cref=\"TimeSpan\"/> instance fails.</exception>\n        private static Duration ParseTimeSpan(ReadOnlySpan<char> valueSpan, CultureInfo cultureInfo)\n        {\n            try\n            {\n                return new Duration(TimeSpan.Parse(valueSpan, cultureInfo));\n            }\n            catch (FormatException e)\n            {\n                throw new FormatException($\"{valueSpan} is not a valid value for {nameof(TimeSpan)}.\", e);\n            }\n        }\n\n        /// <summary>\n        /// Converts a <paramref name=\"value\"/> of <see cref=\"Duration\"/> to its <see cref=\"string\"/> representation.\n        /// </summary>\n        /// <param name=\"context\">Context information used for conversion.</param>\n        /// <param name=\"cultureInfo\">The culture specifier to use, currently ignored during conversion.</param>\n        /// <param name=\"value\">Duration value to convert from.</param>\n        /// <param name=\"destinationType\">Type being evaluated for conversion.</param>\n        /// <returns>A <see cref=\"string\"/> representing the <see cref=\"Duration\"/> specified by <paramref name=\"value\"/>.</returns>\n        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cultureInfo, object value, Type destinationType)\n        {\n            ArgumentNullException.ThrowIfNull(destinationType);\n\n            // Check that we actually support the conversion, NULL value results in string.Empty, others throw\n            if (value is not Duration duration || (destinationType != typeof(InstanceDescriptor) && destinationType != typeof(string)))\n                return base.ConvertTo(context, cultureInfo, value, destinationType);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/DurationConverter.cs#L62-L98","documentation":"DurationConverter.ParseTimeSpan wraps a FormatException from TimeSpan.Parse and rethrows it with a message naming the offending valueSpan, preserving the inner exception. It fires during ConvertFrom when a string (typically from XAML) cannot be parsed as a TimeSpan for a Duration. The wrapper exists so the error message states which value failed.","triggerScenarios":"Calling DurationConverter.ConvertFrom (or the TypeConverter pipeline during XAML/BAML loading) with a string that TimeSpan.Parse rejects, e.g. \"abc\", \"1:2\", or an empty string.","commonSituations":"Typos in XAML animation durations; culture mismatch where the expected ':'-separated format differs; localized resource strings containing an invalid duration; binding a string property to a Duration target without conversion.","solutions":["Correct the duration string to a parseable TimeSpan format (e.g. \"0:0:5\" or \"00:00:05\")","Inspect the inner FormatException for the exact parse failure","Use TimeSpan.TryParse to validate user-provided duration strings before assignment"],"exampleFix":"// before\n<Storyboard Duration=\"five seconds\" />\n// after\n<Storyboard Duration=\"0:0:5\" />","handlingStrategy":"try-catch","validationCode":"if (TimeSpan.TryParse(value, CultureInfo.InvariantCulture, out _)) { /* safe */ }","typeGuard":"bool IsValidDurationString(string s) => TimeSpan.TryParse(s, CultureInfo.InvariantCulture, out _);","tryCatchPattern":"try { var d = (Duration)converter.ConvertFrom(null, culture, text); } catch (FormatException e) { log(e.InnerException ?? e); useDefaultDuration(); }","preventionTips":["Use TimeSpan.TryParse for untrusted strings","Keep duration strings in invariant, canonical \"hh:mm:ss\" form","Test XAML resource duration strings in all target cultures"],"tags":["wpf","xaml","typeconverter","format"],"backgroundTag":"invalid-duration-format","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"}