tui-cs/Terminal.Gui · error · JsonException

{value}: Invalid Rune

Error message

{value}: Invalid Rune

What it means

Thrown by RuneJsonConverter.Read (RuneJsonConverter.cs:64-67) when a Rune string value does NOT start with U+/\U (so it is treated as a literal glyph) but its length is 0 or greater than 2. A literal Rune glyph must be a single character or a two-character surrogate/combining-mark pair. Empty strings and 3+ character literals are rejected.

Source

Thrown at Terminal.Gui/Configuration/RuneJsonConverter.cs:66

                            throw new JsonException ($"{value}: Invalid Rune.");
                        }

                        if (codePoints.Length > 0)
                        {
                            first = (int)codePoints [0];
                        }

                        if (codePoints.Length == 2)
                        {
                            second = (int)codePoints [1];
                        }
                    }
                    else
                    {
                        // Handle single character, surrogate pair, or combining mark + char
                        if (value is { Length: 0 or > 2 })
                        {
                            throw new JsonException ($"{value}: Invalid Rune");
                        }

                        if (value is { Length: > 0 })
                        {
                            first = value [0];
                        }

                        if (value is { Length: 2 })
                        {
                            second = value [1];
                        }
                    }

                    Rune result;

                    if (second == RuneExtensions.MaxUnicodeCodePoint + 1)
                    {
                        // Single codepoint

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Provide a single character for the Rune (e.g. "☑") or a two-character surrogate/combining-mark pair.
  2. If you have a codepoint, use the encoded form "U+2611" instead of a literal.
  3. Do not leave Rune fields empty; supply a default glyph (e.g. space " " or the replacement character).
  4. For multi-character sequences, encode each as U+ with at most two codepoints, or reconsider whether a Rune is the right type.

Example fix

// before (empty / too long literal)
"Check": ""
// or
"Check": "yes"

// after (single glyph)
"Check": "☑"
// or encoded
"Check": "U+2611"
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidLiteralRune (string? value)
{
    if (value is null) return false;
    if (value.StartsWith ("U+", StringComparison.OrdinalIgnoreCase)
        || value.StartsWith ("\\U", StringComparison.OrdinalIgnoreCase))
        return true; // encoded form, validated elsewhere
    return value.Length is 1 or 2;
}

if (!IsValidLiteralRune (runeValue))
{
    // supply a single glyph, a surrogate pair, or use U+ encoded form
}

Type guard

static bool IsValidLiteralRune (string? value)
{
    if (value is null) return false;
    if (value.StartsWith ("U+", StringComparison.OrdinalIgnoreCase)
        || value.StartsWith ("\\U", StringComparison.OrdinalIgnoreCase))
        return true;
    return value.Length is 1 or 2;
}

Try / catch

try
{
    ConfigurationManager.Load (configJson);
}
catch (JsonException ex) when (ex.Message.Contains ("Invalid Rune"))
{
    // A literal Rune was empty or >2 chars. Supply a single glyph or use U+ form, then reload.
}

Prevention

When it happens

Trigger: A Rune config value is an empty string "", or a literal string of 3+ characters that is not in encoded U+ form, e.g. "abc". Since it does not start with U+/\U, the converter treats it as a raw glyph and enforces length 1 or 2.

Common situations: User leaves a Rune field empty. User puts a multi-character word ("yes") where a single glyph is expected. User pastes a grapheme cluster that the OS decomposed into 3+ chars. Confusion between the literal-glyph form and the U+ encoded form.

Related errors


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