tui-cs/Terminal.Gui · error · JsonException

{value}: Invalid Rune. The second codepoint is not valid: {s

Error message

{value}: Invalid Rune. The second codepoint is not valid: {second}.

What it means

On the two-codepoint path where the pair is NOT a valid surrogate pair, the converter checks Rune.IsValid(second). This throws when the second codepoint is itself not a valid scalar value (lone surrogate or out of range), so it cannot be treated as a combining mark either.

Source

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

                    {
                        // Single codepoint
                        if (!Rune.TryCreate (first, out result))
                        {
                            throw new JsonException ($"{value}: Invalid Rune");
                        }

                        return result;
                    }

                    // Surrogate pair?
                    if (Rune.TryCreate ((char)first, (char)second, out result))
                    {
                        return result;
                    }

                    if (!Rune.IsValid (second))
                    {
                        throw new JsonException ($"{value}: Invalid Rune. The second codepoint is not valid: {second}.");
                    }

                    var cm = new Rune (second);

                    if (!cm.IsCombiningMark ())
                    {
                        throw new JsonException ($"{value}: Invalid Rune. The second codepoint is not a combining mark: {cm}.");
                    }

                    // not a surrogate pair, so a combining mark + char?
                    string combined = string.Concat ((char)first, (char)second).Normalize ();

                    if (!Rune.IsValid (combined [0]))
                    {
                        throw new JsonException ($"{value}: Invalid combined Rune.");
                    }

                    return new (combined [0]);

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Make the second codepoint a valid scalar value.
  2. If a combining mark was intended, use a real combining codepoint (e.g. U+0301 combining acute accent).
  3. If an astral character was intended, encode it as a correct surrogate pair.

Example fix

// before
"Glyph": "U+0041U+D800"
// after
"Glyph": "U+0041U+0301"
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidTwoCodepointRune (string s)
{
    // For "U+XXXXU+YYYY" style: both must be valid scalars and either a
    // surrogate pair or base+combining-mark.
    var cps = System.Text.RegularExpressions.Regex.Matches (
        s, @"(?:\\[uU]\+?|U\+)([0-9A-Fa-f]{1,8})")
        .Select (m => uint.Parse (m.Groups [1].Value,
            System.Globalization.NumberStyles.HexNumber)).ToArray ();
    return cps.Length == 2 && System.Text.Rune.IsValid (cps [1]);
}

Try / catch

try { ConfigurationManager.Apply (); }
catch (JsonException ex) when (ex.Message.Contains ("second codepoint is not valid"))
{ /* report offending value from ex.Message */ }

Prevention

When it happens

Trigger: Config supplies two U+ codepoints that do not form a surrogate pair, and the second is a lone surrogate (e.g. "U+0041U+D800" — 'A' followed by a lone high surrogate).

Common situations: Manually building a combining sequence and mistyping the second codepoint; a truncated surrogate pair pasted as two separate invalid values.

Related errors


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