AvaloniaUI/Avalonia · error · FormatException

Invalid HSL color string

Error message

Invalid HSL color string: '{s}'.

What it means

HslColor.Parse parses a 'hsl(...)' / 'hsla(...)' CSS-style string into an HslColor. After stripping the prefix and splitting channels it must satisfy TryParse's grammar; on any malformed token, prefix mismatch, or out-of-range channel it returns false and Parse throws FormatException including the offending string for diagnostics.

Solutions

  1. Call HslColor.TryParse(s, out var c) first and only fall back to Parse for the exception path.
  2. Normalize the input: ensure hsl()/hsla() prefix, comma separators, and % on S and L.
  3. If accepting hex/RGB too, dispatch by prefix to Color.Parse, HslColor.Parse, or HsvColor.Parse.
  4. Show the user the exact failing string in your UI error message.

Example fix

// before
var c = HslColor.Parse(userInput); // throws on any malformed string

// after
if (!HslColor.TryParse(userInput?.Trim(), out var c))
    throw new ArgumentException($"'{userInput}' is not a valid hsl()/hsla() color.");
// or accept multiple formats:
static object ParseColor(string s) => s.StartsWith("hsl") ? (object)HslColor.Parse(s)
    : s.StartsWith("hsv") ? HsvColor.Parse(s)
    : Color.Parse(s);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!HslColor.TryParse(s?.Trim(), out var c))
    throw new ArgumentException($"'{s}' is not a valid hsl()/hsla() color.");

Type guard

static bool IsHslColorString(string? s)
{
    var t = s?.Trim();
    return t != null
        && (t.StartsWith("hsl(", StringComparison.OrdinalIgnoreCase)
            || t.StartsWith("hsla(", StringComparison.OrdinalIgnoreCase))
        && t.EndsWith(")")
        && HslColor.TryParse(t, out _);
}

Try / catch

try { return HslColor.Parse(s); }
catch (FormatException ex) { throw new ArgumentException($"Bad HSL: '{s}'", ex); }

Prevention

When it happens

Trigger: Passing 'hsl(240,100%,50%)' missing a channel; 'hsl(240 100 50)' without the % required on saturation/lightness; an 'rgb(...)' string fed to HslColor.Parse by mistake; trailing characters after the closing paren; commas vs spaces grammar mismatch.

Common situations: Loading theme colors from a user-edited config or CSS file with inconsistent notation; copy-pasting a hex color (#336699) into a field typed as HSL; binding a textbox directly to HslColor.Parse without validation.

Related errors


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

Appendix: source

Thrown at src/Avalonia.Base/Media/HslColor.cs:226

        /// <summary>
        /// Parses an HSL color string.
        /// </summary>
        /// <param name="s">The HSL color string to parse.</param>
        /// <returns>The parsed <see cref="HslColor"/>.</returns>
        public static HslColor Parse(string s)
        {
            if (s is null)
            {
                throw new ArgumentNullException(nameof(s));
            }

            if (TryParse(s, out HslColor hslColor))
            {
                return hslColor;
            }

            throw new FormatException($"Invalid HSL color string: '{s}'.");
        }

        /// <summary>
        /// Parses an HSL color string.
        /// </summary>
        /// <param name="s">The HSL color string to parse.</param>
        /// <param name="hslColor">The parsed <see cref="HslColor"/>.</param>
        /// <returns>True if parsing was successful; otherwise, false.</returns>
        public static bool TryParse(string? s, out HslColor hslColor)
        {
            bool prefixMatched = false;

            hslColor = default;

            if (s is null)
            {
                return false;
            }

View on GitHub (pinned to 11c5427268)