tui-cs/Terminal.Gui · error · JsonException
{propertyName}: Unexpected StartObject token when parsing Ke
Error message
{propertyName}: Unexpected StartObject token when parsing Key: {reader.TokenType}. What it means
Thrown by KeyCodeJsonConverter.Read (KeyCodeJsonConverter.cs:123) when the initial token is not StartObject. The converter expects a Key to be a JSON object {"Key": ..., "Modifiers": [...]}. Supplying a bare string, number, or array for a KeyCode-typed property hits this terminal throw after the if-block.
Source
Thrown at Terminal.Gui/Configuration/KeyCodeJsonConverter.cs:123
}
break;
default:
throw new JsonException ($"{propertyName}: Unexpected Key property.");
}
}
}
foreach (KeyCode modifier in modifiers)
{
key |= modifier;
}
return key;
}
throw new JsonException ($"{propertyName}: Unexpected StartObject token when parsing Key: {reader.TokenType}.");
}
public override void Write (Utf8JsonWriter writer, KeyCode value, JsonSerializerOptions options)
{
writer.WriteStartObject ();
var keyName = (value & ~KeyCode.CtrlMask & ~KeyCode.ShiftMask & ~KeyCode.AltMask).ToString ();
writer.WriteString ("Key", keyName);
Dictionary<string, KeyCode> modifierDict = new ()
{
{ "Shift", KeyCode.ShiftMask }, { "Ctrl", KeyCode.CtrlMask }, { "Alt", KeyCode.AltMask }
};
List<string> modifiers = new ();
foreach (KeyValuePair<string, KeyCode> pair in modifierDict)View on GitHub (pinned to 2e47b11478)
Solutions
- Write KeyCode properties as JSON objects: {"Key":"Enter"} or {"Key":"A","Modifiers":["Ctrl"]}.
- If the property is actually Key[] (array), use the string-array form and ensure the property type is Key[], not KeyCode.
- Confirm which converter applies to the property type: KeyCode uses the object form, Key[] uses string arrays.
- Validate the token type is StartObject before deserialization.
Example fix
// before (KeyCode property given a scalar)
"Accept": "Enter"
// after (KeyCode property as object)
"Accept": { "Key": "Enter" } Defensive patterns
Strategy: validation
Validate before calling
using System.Text.Json;
static bool KeyPropertyIsObject (string json, string propertyName)
{
using JsonDocument doc = JsonDocument.Parse (json);
if (!doc.RootElement.TryGetProperty (propertyName, out JsonElement el)) return true;
return el.ValueKind == JsonValueKind.Object;
}
if (!KeyPropertyIsObject (configJson, "Accept"))
{
// wrap the scalar into {"Key": ...} before loading
} Type guard
static bool IsKeyCodeObject (JsonElement el) => el.ValueKind == JsonValueKind.Object;
Try / catch
try
{
ConfigurationManager.Load (configJson);
}
catch (JsonException ex) when (ex.Message.Contains ("Unexpected StartObject token when parsing Key"))
{
// A KeyCode property was given a scalar. Rewrite it as {"Key": ...} and reload.
} Prevention
- Write KeyCode properties as JSON objects {"Key": "Enter"}.
- Confirm whether the property type is KeyCode (object form) or Key[] (string array form).
- Do not mix the two Key serialization formats.
- Use a Terminal.Gui-serialized config as the canonical reference.
When it happens
Trigger: A KeyCode-typed config property is given as a scalar (e.g. "Accept": "Enter" or "Accept": 13) instead of the object form {"Key":"Enter"}. The reader is not positioned on a StartObject token.
Common situations: User writes the short string form where the object KeyCode form is expected (note: Key[] arrays use strings, but a single KeyCode property uses the object form). Tooling emits scalars. Mixing up the two Key serialization formats (object KeyCode vs string-array Key[]).
Related errors
- {propertyName}: Unexpected Key property.
- Expected start of array for Key[].
- Expected string token in Key array, got {reader.TokenType}.
- {propertyName}: "{reader.GetString ()}" is not a valid Key.
- {propertyName}: Error parsing Key value: {ioe.Message}
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/a22fcc8d4f3d307e.
Report an issue: GitHub.