spectreconsole/spectre.console · error · InvalidOperationException
Invalid hex color '#{hex}'.
Error message
Invalid hex color '#{hex}'. What it means
ParseHexColor completed without throwing but the hex string was empty or had a length other than 3 or 6, so no Color could be produced. Reports 'Invalid hex color #{hex}.'
Source
Thrown at src/Spectre.Console.Ansi/AnsiMarkupTagParser.cs:10
namespace Spectre.Console;
internal static class AnsiMarkupTagParser
{
public static (Style Style, Link? Link) Parse(string text)
{
var result = Parse(text, out var error);
if (error != null)
{
throw new InvalidOperationException(error);
}
return result ?? throw new InvalidOperationException("Could not parse style.");
}
public static bool TryParse(string text, [NotNullWhen(true)] out (Style Style, Link?)? result)
{
result = Parse(text, out _);
return result != null;
}
private static (Style Style, Link? Link)? Parse(string text, out string? error)
{
var effectiveDecoration = (Decoration?)null;
var effectiveForeground = (Color?)null;
var effectiveBackground = (Color?)null;
var effectiveLink = (string?)null;
View on GitHub (pinned to 0acc92fada)
Solutions
- Provide exactly 6 hex digits (#RRGGBB) or 3 (#RGB)
- Format integers as X6 to guarantee 6 digits, e.g. $"#{value:X6}"
- Validate length before embedding
Example fix
// before
AnsiMarkup.Parse($"[#{value:X}]text[/]"); // X can produce fewer than 6 digits
// after
AnsiMarkup.Parse($"[#{value:X6}]text[/]"); Defensive patterns
Strategy: validation
Validate before calling
public static bool IsValidHexLength(string token)
{
var h = token.TrimStart('#');
return h.Length == 3 || h.Length == 6;
} Try / catch
try { AnsiMarkup.Parse(markup); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Invalid hex color"))
{ /* pad to 6 digits with value.ToString("X6") */ } Prevention
- Always use 6 digits (#RRGGBB) for programmatic colors
- Pad with X6 format specifier to avoid short strings
- Validate length before building the tag
When it happens
Trigger: A `#`-prefix with the wrong digit count: `[#1234]` (4 digits), `[#1234567]` (7 digits), `[#]` (empty), or `[#12]` (2 digits).
Common situations: Code that builds hex from a value not padded to 6 digits; stripping/trimming that shortens the string; off-by-one in substring slicing.
Related errors
- Invalid hex color '#{hex}'. {ex.Message}
- Color number must be greater than or equal to 0 (was {number
- Color number must be less than or equal to 255 (was {number}
- Could not find color '{part}'.
- Could not find color or style '{part}'.
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/8cafe2089ac736ef.
Report an issue: GitHub.