AvaloniaUI/Avalonia · error · FormatException

Invalid HSV color string: '{s}'.

Error message

Invalid HSV color string: '{s}'.

What it means

HsvColor.Parse parses a 'hsv(...)' / 'hsva(...)' string into an HsvColor and throws FormatException on malformed input. It mirrors HslColor.Parse: prefix check, channel split, and per-channel range validation must all pass inside TryParse.

Source

Thrown at src/Avalonia.Base/Media/HsvColor.cs:256

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

            if (TryParse(s, out HsvColor hsvColor))
            {
                return hsvColor;
            }

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

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

            hsvColor = default;

            if (s is null)
            {
                return false;
            }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Call HsvColor.TryParse(s, out var c) and report a friendly error on failure.
  2. Confirm the prefix is exactly 'hsv' or 'hsva' and the channel separators match the parser grammar.
  3. Normalize the picker output before parsing (consistent separators, channel order, % vs raw).
  4. Dispatch by prefix if multiple color notations are supported.

Example fix

// before
var c = HsvColor.Parse(userInput); // throws on malformed hsv string

// after
if (!HsvColor.TryParse(userInput?.Trim(), out var c))
    return Result.Fail($"'{userInput}' is not a valid hsv()/hsva() color.");
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

static bool IsHsvColorString(string? s)
{
    var t = s?.Trim();
    return t != null
        && (t.StartsWith("hsv(", StringComparison.OrdinalIgnoreCase)
            || t.StartsWith("hsva(", StringComparison.OrdinalIgnoreCase))
        && t.EndsWith(")")
        && HsvColor.TryParse(t, out _);
}

Try / catch

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

Prevention

When it happens

Trigger: Passing 'hsv(240,100,100)' with wrong separator grammar; missing a channel; using 'hsb()' (an alternate name) when the parser only accepts hsv/hsva; trailing junk after the closing paren; S/V given as percentages when the grammar expects numbers (or vice versa).

Common situations: Loading HSV strings from a picker UI that emits a different format than the parser expects; copy-pasting CSS (which does not standardize hsv) into an HSV field; mixing up hsl and hsv notations.

Related errors


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