tui-cs/Terminal.Gui · error · JsonException
Expected start of array for Key[].
Error message
Expected start of array for Key[].
What it means
Thrown by KeyArrayJsonConverter.Read (KeyArrayJsonConverter.cs:20-23) when the token is neither Null nor StartArray. Key[] config properties must be JSON string arrays like ["Ctrl+A", "Home"]. A non-array (object, number, bare string) for a Key[] property produces this JsonException.
Source
Thrown at Terminal.Gui/Configuration/KeyArrayJsonConverter.cs:22
namespace Terminal.Gui.Configuration;
/// <summary>
/// Serializes and deserializes <see cref="Key"/> arrays as JSON string arrays (e.g. <c>["Ctrl+A", "Home"]</c>).
/// Each element uses <see cref="Key.ToString()"/> for writing and <see cref="Key.TryParse"/> for reading.
/// </summary>
public class KeyArrayJsonConverter : JsonConverter<Key []?>
{
/// <inheritdoc/>
public override Key []? Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
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 ()!;
View on GitHub (pinned to 2e47b11478)
Solutions
- Wrap the key value(s) in a JSON array even for a single binding: ["Enter"].
- Use null explicitly if the property should be cleared, since null is accepted (returns null).
- Cross-check the format against a serialized sample produced by Terminal.Gui itself.
- Validate the config JSON with a schema that enforces array type for Key[] properties.
Example fix
// before "Accept": "Enter" // after "Accept": ["Enter"]
Defensive patterns
Strategy: validation
Validate before calling
using System.Text.Json;
static bool IsKeyArrayProperty (string json, string propertyName)
{
using JsonDocument doc = JsonDocument.Parse (json);
if (!doc.RootElement.TryGetProperty (propertyName, out JsonElement el)) return true;
return el.ValueKind == JsonValueKind.Array || el.ValueKind == JsonValueKind.Null;
}
if (!IsKeyArrayProperty (configJson, "Accept"))
{
// wrap the scalar in an array before loading
} Type guard
static bool IsKeyArray (JsonElement el)
=> el.ValueKind == JsonValueKind.Array || el.ValueKind == JsonValueKind.Null; Try / catch
try
{
ConfigurationManager.Load (configJson);
}
catch (JsonException ex) when (ex.Message.Contains ("Expected start of array for Key[]"))
{
// Rewrite the scalar/property to a JSON array ["..."] and reload.
} Prevention
- Always wrap Key[] bindings in a JSON array, even single bindings.
- Use null to clear a Key[] property (it is accepted).
- Validate config with a schema enforcing array type for Key[] properties.
- Use a Terminal.Gui-serialized config as the canonical format reference.
When it happens
Trigger: A keybinding config JSON has a Key[] property (e.g. a command's bound keys) written as a single string "Ctrl+A" or an object instead of an array ["Ctrl+A"].
Common situations: User writes a single keybinding as "Accept": "Enter" instead of "Accept": ["Enter"]. Config migration from a format that uses scalars for single bindings. Copying a keybinding value from elsewhere that omitted the brackets.
Related errors
- Expected string token in Key array, got {reader.TokenType}.
- {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/c8346cfbe856bfd6.
Report an issue: GitHub.