iOfficeAI/OfficeCLI · error · ArgumentException
Invalid color value: '{original}'. Hue must be a number in d
Error message
Invalid color value: '{original}'. Hue must be a number in degrees. What it means
Thrown by ParseHueDegrees when the hue token, after stripping an optional 'deg' suffix, is not a parseable number. Hue in hsl()/hsla() is an angle in degrees; it may wrap (modulo 360 is applied) but it must be numeric. Non-numeric tokens like 'red' or empty strings are rejected.
Source
Thrown at src/officecli/Core/ParseHelpers.cs:200
}
else
{
if (!double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out a) || a < 0 || a > 1)
throw new ArgumentException($"Invalid color value: '{original}'. Alpha must be 0-1 (e.g. 0.5) or 0%-100%.");
}
return (byte)Math.Round(a * 255.0);
}
private static double ParseHueDegrees(string token, string original)
{
token = token.Trim();
// Strip an optional `deg` suffix (CSS allows it; other angle units
// — turn/rad/grad — are out of scope for the input vocabulary we care
// about and would just need their own multipliers if asked for).
if (token.EndsWith("deg", StringComparison.OrdinalIgnoreCase))
token = token[..^3].Trim();
if (!double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out var h))
throw new ArgumentException($"Invalid color value: '{original}'. Hue must be a number in degrees.");
h %= 360;
if (h < 0) h += 360;
return h;
}
private static double ParsePercent01(string token, string original)
{
token = token.Trim();
if (!token.EndsWith('%'))
throw new ArgumentException($"Invalid color value: '{original}'. HSL saturation/lightness must be expressed as a percentage (e.g. 50%).");
if (!double.TryParse(token[..^1], NumberStyles.Float, CultureInfo.InvariantCulture, out var pct)
|| pct < 0 || pct > 100)
throw new ArgumentException($"Invalid color value: '{original}'. HSL saturation/lightness must be 0%-100%.");
return pct / 100.0;
}
private static (byte R, byte G, byte B) HslToRgb(double h, double s, double l)
{View on GitHub (pinned to 1ced45e900)
Solutions
- Supply hue as a number of degrees, e.g. hsl(120,50%,50%) or hsl(120deg,50%,50%).
- If you only have a named color, convert it to HSL first (do not put the name in the hue slot).
- Validate the hue token is numeric before building the hsl() string.
Example fix
// before var c = "hsl(red,50%,50%)"; ParseColor(c); // throws 288 // after var c = "hsl(0,50%,50%)"; // 0 deg = red ParseColor(c);
Defensive patterns
Strategy: validation
Validate before calling
if (!double.TryParse(hueToken.TrimEnd("deg".ToCharArray()), NumberStyles.Float, CultureInfo.InvariantCulture, out _))
hueToken = "0"; Type guard
static bool IsValidHue(string token)
{
var t = token.Trim();
if (t.EndsWith("deg", StringComparison.OrdinalIgnoreCase)) t = t[..^3].Trim();
return double.TryParse(t, CultureInfo.InvariantCulture, out _);
} Try / catch
try { color = ParseColor(spec); }
catch (ArgumentException ex) when (ex.Message.Contains("Hue"))
{ spec = "hsl(0,50%,50%)"; } Prevention
- Always supply hue as a numeric degree.
- Convert named colors to HSL before building an hsl() string.
- Validate the hue token is non-empty.
When it happens
Trigger: Passing hsl(red,50%,50%); passing hsl(,50%,50%) (empty hue); a hue value that was meant to be a named color leaking into the hue slot.
Common situations: Mixing up CSS named-color input with HSL; a templating bug that left the hue token blank; copy-pasting an HSL triple that used a different delimiter and lost the hue.
Related errors
- Invalid color value: '{original}'. HSL saturation/lightness
- Invalid color value: '{original}'. HSL saturation/lightness
- Invalid color value: '{original}'. RGB percentage components
- Invalid color value: '{original}'. RGB components must be 0-
- Invalid color value: '{original}'. Alpha percentage must be
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/08c2eff8c1f1bc7c.
Report an issue: GitHub.