tui-cs/Terminal.Gui · error · ArgumentException

Invalid color name: {kvp.Key}

Error message

Invalid color name: {kvp.Key}

What it means

Thrown by the setter of ColorExtensions.ColorToName16Map when a Dictionary<ColorName16,string> entry's key cannot be parsed back into a ColorName16 enum value via Enum.TryParse. It is an ArgumentException naming the offending kvp.Key. This is a configuration-validation error in the 16-color name mapping, not a runtime color parse error.

Source

Thrown at Terminal.Gui/Drawing/Color/Color.cs:205

    public static Dictionary<ColorName16, string> Colors16
    {
        get =>

            // Transform _colorToNameMap into a Dictionary<ColorNames,string>
            ColorExtensions.ColorToName16Map!.ToDictionary (static kvp => kvp.Value, static kvp => kvp.Key.ToString ("g"));
        set
        {
            // Transform Dictionary<ColorNames,string> into _colorToNameMap
            ColorExtensions.ColorToName16Map = value.ToFrozenDictionary (GetColorToNameMapKey, GetColorToNameMapValue);

            return;

            static Color GetColorToNameMapKey (KeyValuePair<ColorName16, string> kvp) => new (kvp.Value);

            static ColorName16 GetColorToNameMapValue (KeyValuePair<ColorName16, string> kvp) =>
                Enum.TryParse (kvp.Key.ToString (), true, out ColorName16 colorName)
                    ? colorName
                    : throw new ArgumentException ($"Invalid color name: {kvp.Key}");
        }
    }

    /// <summary>
    ///     Gets the <see cref="Color"/> using a legacy 16-color <see cref="ColorName16"/> value. <see langword="get"/> will
    ///     return the closest 16 color match to the true color when no exact value is found.
    /// </summary>
    /// <remarks>
    ///     Get returns the <see cref="GetClosestNamedColor16(Color)"/> of the closest 24-bit color value. Set sets the RGB
    ///     value using a hard-coded map.
    /// </remarks>
    public AnsiColorCode GetAnsiColorCode () => ColorExtensions.ColorName16ToAnsiColorMap [GetClosestNamedColor16 ()];

    /// <summary>
    ///     Gets the <see cref="Color"/> using a legacy 16-color <see cref="ColorName16"/> value. <see langword="get"/>
    ///     will return the closest 16 color match to the true color when no exact value is found.
    /// </summary>
    /// <remarks>

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Ensure every dictionary key is a defined ColorName16 enum value (Enum.IsDefined check).
  2. Validate keys against Enum.GetNames<ColorName16>() before assigning the map.
  3. Correct or remove the offending entry reported in the message.

Example fix

// before
ColorExtensions.ColorToName16Map = customMap;

// after
foreach (var k in customMap.Keys)
    if (!Enum.IsDefined(k)) throw new InvalidOperationException($"Bad ColorName16 key: {k}");
ColorExtensions.ColorToName16Map = customMap;
Defensive patterns

Strategy: validation

Validate before calling

foreach (var k in map.Keys)
    if (!Enum.IsDefined(k)) throw new InvalidOperationException($"Bad key {k}");
ColorExtensions.ColorToName16Map = map;

Type guard

static bool IsValidColorName16Map(Dictionary<ColorName16,string> map) => map.Keys.All(Enum.IsDefined);

Try / catch

try { ColorExtensions.ColorToName16Map = map; } catch (ArgumentException ex) { /* ex.Message names bad key */ }

Prevention

When it happens

Trigger: Assigning ColorExtensions.ColorToName16Map with a dictionary whose keys include undefined ColorName16 enum values (e.g. a cast like (ColorName16)999) or keys whose ToString() is not a valid enum name.

Common situations: Custom theme/configuration files that supply a color-name-to-string mapping with an invalid or outdated ColorName16 identifier, or programmatically building the dictionary with invalid enum casts.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/bab41e8e58498931. Report an issue: GitHub.