{"record":{"id":"0373b6324a432fb8","repo":"tui-cs/Terminal.Gui","slug":"value-invalid-rune-the-second-codepoint-is-not","errorCode":null,"errorMessage":"{value}: Invalid Rune. The second codepoint is not valid: {second}.","messagePattern":"(.+?): Invalid Rune\\. The second codepoint is not valid: (.+?)\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Configuration/RuneJsonConverter.cs","lineNumber":101,"sourceCode":"                    {\n                        // Single codepoint\n                        if (!Rune.TryCreate (first, out result))\n                        {\n                            throw new JsonException ($\"{value}: Invalid Rune\");\n                        }\n\n                        return result;\n                    }\n\n                    // Surrogate pair?\n                    if (Rune.TryCreate ((char)first, (char)second, out result))\n                    {\n                        return result;\n                    }\n\n                    if (!Rune.IsValid (second))\n                    {\n                        throw new JsonException ($\"{value}: Invalid Rune. The second codepoint is not valid: {second}.\");\n                    }\n\n                    var cm = new Rune (second);\n\n                    if (!cm.IsCombiningMark ())\n                    {\n                        throw new JsonException ($\"{value}: Invalid Rune. The second codepoint is not a combining mark: {cm}.\");\n                    }\n\n                    // not a surrogate pair, so a combining mark + char?\n                    string combined = string.Concat ((char)first, (char)second).Normalize ();\n\n                    if (!Rune.IsValid (combined [0]))\n                    {\n                        throw new JsonException ($\"{value}: Invalid combined Rune.\");\n                    }\n\n                    return new (combined [0]);","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Configuration/RuneJsonConverter.cs#L83-L119","documentation":"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.","triggerScenarios":"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).","commonSituations":"Manually building a combining sequence and mistyping the second codepoint; a truncated surrogate pair pasted as two separate invalid values.","solutions":["Make the second codepoint a valid scalar value.","If a combining mark was intended, use a real combining codepoint (e.g. U+0301 combining acute accent).","If an astral character was intended, encode it as a correct surrogate pair."],"exampleFix":"// before\n\"Glyph\": \"U+0041U+D800\"\n// after\n\"Glyph\": \"U+0041U+0301\"","handlingStrategy":"validation","validationCode":"static bool IsValidTwoCodepointRune (string s)\n{\n    // For \"U+XXXXU+YYYY\" style: both must be valid scalars and either a\n    // surrogate pair or base+combining-mark.\n    var cps = System.Text.RegularExpressions.Regex.Matches (\n        s, @\"(?:\\\\[uU]\\+?|U\\+)([0-9A-Fa-f]{1,8})\")\n        .Select (m => uint.Parse (m.Groups [1].Value,\n            System.Globalization.NumberStyles.HexNumber)).ToArray ();\n    return cps.Length == 2 && System.Text.Rune.IsValid (cps [1]);\n}","typeGuard":null,"tryCatchPattern":"try { ConfigurationManager.Apply (); }\ncatch (JsonException ex) when (ex.Message.Contains (\"second codepoint is not valid\"))\n{ /* report offending value from ex.Message */ }","preventionTips":["When authoring two-codepoint sequences, verify both are valid scalars with Rune.IsValid.","Prefer real combining marks (U+0300–U+036F) over hand-built pairs."],"tags":["config","json","unicode","rune","deserialization"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}