{"record":{"id":"d1ff60f74298c361","repo":"AvaloniaUI/Avalonia","slug":"text-decoration-already-specified","errorCode":null,"errorMessage":"Text decoration already specified.","messagePattern":"Text decoration already specified\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Media/TextDecorationCollection.cs","lineNumber":40,"sourceCode":"        \n        /// <summary>\n        /// Parses a <see cref=\"TextDecorationCollection\"/> string.\n        /// </summary>\n        /// <param name=\"s\">The string.</param>\n        /// <returns>The <see cref=\"TextDecorationCollection\"/>.</returns>\n        public static TextDecorationCollection Parse(string s)\n        {\n            var locations = new List<TextDecorationLocation>();\n\n            using (var tokenizer = new SpanStringTokenizer(s, ',', \"Invalid text decoration.\"))\n            {\n                while (tokenizer.TryReadSpan(out var name))\n                {\n                    var location = GetTextDecorationLocation(name);\n\n                    if (locations.Contains(location))\n                    {\n                        throw new ArgumentException(\"Text decoration already specified.\", nameof(s));\n                    }\n\n                    locations.Add(location);\n                }\n            }\n\n            var textDecorations = new TextDecorationCollection();\n\n            foreach (var textDecorationLocation in locations)\n            {\n                textDecorations.Add(new TextDecoration { Location = textDecorationLocation });\n            }\n\n            return textDecorations;\n        }\n\n        /// <summary>\n        /// Parses a <see cref=\"TextDecorationLocation\"/> string.","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Media/TextDecorationCollection.cs#L22-L58","documentation":"Thrown by TextDecorationCollection.Parse when the same decoration location appears more than once in the comma-separated input. Parse collects locations into a list and rejects duplicates because a TextDecorationCollection cannot meaningfully contain two identical locations (e.g. two 'Underline' entries).","triggerScenarios":"Strings like 'Underline,Underline', 'Strikethrough,Baseline,Strikethrough', or any token repeated in the decoration list passed to Parse or set via a XAML/markup text decorations attribute.","commonSituations":"Dynamically building a decoration string by concatenating flags without de-duplicating; merging decoration settings from multiple sources; copy-paste duplication in XAML or style setters.","solutions":["List each decoration location at most once: 'Strikethrough,Underline'.","De-duplicate before building the string: string.Join(',', selected.Distinct()).","Use the enum flags or distinct collection rather than a free-form string when composing decorations."],"exampleFix":"// before\nvar d = TextDecorationCollection.Parse(\"Underline,Underline\");\n\n// after\nvar d = TextDecorationCollection.Parse(string.Join(\",\", selected.Distinct()));","handlingStrategy":"validation","validationCode":"var dedup = string.Join(\",\", tokens.Distinct(StringComparer.OrdinalIgnoreCase));\nvar d = TextDecorationCollection.Parse(dedup);","typeGuard":null,"tryCatchPattern":"try { var d = TextDecorationCollection.Parse(s); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"already specified\"))\n{ /* de-duplicate and retry */ }","preventionTips":["De-duplicate decoration tokens before joining into a string.","Compose decorations from a set rather than concatenating flags."],"tags":["avalonia","text","text-decoration","duplicate","parse"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}