AvaloniaUI/Avalonia · error · FormatException

Invalid HSL color string: '{s}'.

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.

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)

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.