AvaloniaUI/Avalonia · error · ArgumentException

Text decoration already specified.

Error message

Text decoration already specified.

What it means

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).

Source

Thrown at src/Avalonia.Base/Media/TextDecorationCollection.cs:40

        
        /// <summary>
        /// Parses a <see cref="TextDecorationCollection"/> string.
        /// </summary>
        /// <param name="s">The string.</param>
        /// <returns>The <see cref="TextDecorationCollection"/>.</returns>
        public static TextDecorationCollection Parse(string s)
        {
            var locations = new List<TextDecorationLocation>();

            using (var tokenizer = new SpanStringTokenizer(s, ',', "Invalid text decoration."))
            {
                while (tokenizer.TryReadSpan(out var name))
                {
                    var location = GetTextDecorationLocation(name);

                    if (locations.Contains(location))
                    {
                        throw new ArgumentException("Text decoration already specified.", nameof(s));
                    }

                    locations.Add(location);
                }
            }

            var textDecorations = new TextDecorationCollection();

            foreach (var textDecorationLocation in locations)
            {
                textDecorations.Add(new TextDecoration { Location = textDecorationLocation });
            }

            return textDecorations;
        }

        /// <summary>
        /// Parses a <see cref="TextDecorationLocation"/> string.

View on GitHub (pinned to 11c5427268)

Solutions

  1. List each decoration location at most once: 'Strikethrough,Underline'.
  2. De-duplicate before building the string: string.Join(',', selected.Distinct()).
  3. Use the enum flags or distinct collection rather than a free-form string when composing decorations.

Example fix

// before
var d = TextDecorationCollection.Parse("Underline,Underline");

// after
var d = TextDecorationCollection.Parse(string.Join(",", selected.Distinct()));
Defensive patterns

Strategy: validation

Validate before calling

var dedup = string.Join(",", tokens.Distinct(StringComparer.OrdinalIgnoreCase));
var d = TextDecorationCollection.Parse(dedup);

Try / catch

try { var d = TextDecorationCollection.Parse(s); }
catch (ArgumentException ex) when (ex.Message.Contains("already specified"))
{ /* de-duplicate and retry */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/d1ff60f74298c361. Report an issue: GitHub.