tui-cs/Terminal.Gui · error · JsonException
Expected string token in Key array, got {reader.TokenType}.
Error message
Expected string token in Key array, got {reader.TokenType}. What it means
Thrown by KeyArrayJsonConverter.Read (KeyArrayJsonConverter.cs:34-37) inside the array loop when an element token is not a String. Each element of a Key[] JSON array must be a string parseable by Key.TryParse (e.g. "Ctrl+A", "Home", "F1"). A number, boolean, object, or nested array element triggers this.
Source
Thrown at Terminal.Gui/Configuration/KeyArrayJsonConverter.cs:36
}
if (reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException ("Expected start of array for Key[].");
}
List<Key> keys = [];
while (reader.Read ())
{
if (reader.TokenType == JsonTokenType.EndArray)
{
return keys.ToArray ();
}
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException ($"Expected string token in Key array, got {reader.TokenType}.");
}
string keyString = reader.GetString ()!;
keys.Add (Key.TryParse (keyString, out Key key) ? key : Key.Empty);
}
throw new JsonException ("Unexpected end of JSON while reading Key array.");
}
/// <inheritdoc/>
public override void Write (Utf8JsonWriter writer, Key []? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue ();
return;View on GitHub (pinned to 2e47b11478)
Solutions
- Make every element a string token: use the Key.ToString() form (e.g. "Ctrl+A", "D0", "F1") for each entry.
- If you have numeric key codes, convert them to their KeyCode enum name strings before writing the config.
- Do not mix object-form Key entries (that is the KeyCodeJsonConverter format) into a Key[] array.
- Validate each array element is a JSON string before serializing.
Example fix
// before "Accept": ["Ctrl+A", 13] // after "Accept": ["Ctrl+A", "Enter"]
Defensive patterns
Strategy: validation
Validate before calling
using System.Text.Json;
static bool KeyArrayElementsAreStrings (string json, string propertyName)
{
using JsonDocument doc = JsonDocument.Parse (json);
if (!doc.RootElement.TryGetProperty (propertyName, out JsonElement el)) return true;
if (el.ValueKind != JsonValueKind.Array) return false;
foreach (JsonElement item in el.EnumerateArray ())
{
if (item.ValueKind != JsonValueKind.String) return false;
}
return true;
} Type guard
static bool IsKeyArrayElement (JsonElement el) => el.ValueKind == JsonValueKind.String;
Try / catch
try
{
ConfigurationManager.Load (configJson);
}
catch (JsonException ex) when (ex.Message.Contains ("Expected string token in Key array"))
{
// Find the non-string element and replace it with its Key.ToString() form.
} Prevention
- Write every Key[] element as a string in Key.ToString() form (e.g. "Ctrl+A", "Home", "F1").
- Convert numeric key codes to KeyCode enum names before writing config.
- Do not mix object-form Key entries into a Key[] array.
- Validate each array element is a string before serializing.
When it happens
Trigger: A Key[] JSON array contains a non-string element, e.g. ["Ctrl+A", 65] (numeric keyCode) or ["Home", {"Key":"End"}].
Common situations: User writes a numeric key code directly into the array expecting it to be parsed as a KeyCode. A tool emits typed values (numbers) instead of strings. Mixing the Key[] string format with the KeyCodeJsonConverter object format in the same array.
Related errors
- Expected start of array for Key[].
- {propertyName}: "{reader.GetString ()}" is not a valid Key.
- {propertyName}: Error parsing Key value: {ioe.Message}
- {propertyName}: "{mod}" is not a valid modifier.
- {propertyName}: Expected an array of modifiers, but got "{re
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/d9ec24fc8fd1dcd4.
Report an issue: GitHub.